signalr OnDisconnected method - asp.net-core

I am trying to implement an app in which I have used signalr to detect the time at which client is disconnected from server..my hub is like this..
I am using version 0.2.0-alpha
[HubName("TrappistHub")]
public class TrappistHub : Hub
{
public override Task OnDisconnected(bool stopCalled)
{
return base.OnDisconnected(stopCalled);
}
public void SendReport(TestAttendees testAttendee)
{
Clients.All.getReport(testAttendee);
}
}
and DisconnectTime is set default. but when I disconnect from from server OnDisconnected method gets hit after 50 secs instead of 30..and when I set the DisconnectTime to 10 secs or 20 secs it is not getting hit at all..but when I refresh the page it is getting hit...I dont understand why..?

The version you are using (i.e. 0.2.0-alpha) is not supported. Use the new version that shipped last week - 1.0.0-alpha1. See the announcement for more details.

Related

Xamarin.Forms Communication Between Two Pages Within Same App on Different Devices

Technologies, frameworks and devices I'm using:
Framework: Xamarin.Forms
IDE: Visual Studio 2022
Physical Device (smartphone): Zebra TC26 (Android 10)
Physical Device (smartwatch): Samsung Galaxy Watch4 (Android 11)
Problem definition
Currently I have a test Xamarin.Forms project that consists of two different UIs (XAML files):
User Interface 1: HomePage.XAML - This screen should be displayed on the smartphone
User Interface 2: WatchScreen.XAML - This screen should be displayed on the smartwatch
With code below I make sure HomePage.XAML is deployed to a smartphone and watchscreen is deployed to a smartwatch:
Page homePage = new NavigationPage(new HomePage());
// BuildVersionCodes.R is a reference to Android version 11 (mostly now used by Wear OS 3.x)
if (Build.VERSION.SdkInt == BuildVersionCodes.R)
{
// SM-R870 is a reference to the Samsung Galaxy Watch4
// Note: This is needed to ensure the UI is specific to the UI of a smartwatch
if (Build.Model == "SM-R870")
{
Page watchScreen = new NavigationPage(new WatchScreen());
MainPage = watchScreen;
}
}
else
{
MainPage = homePage;
}
Now I want to make these pages on different devices communicate with each other. HomePage.xaml exists within the main Xamarin.Forms project as well as WatchScreen.xaml.
The way I want them to communicate with each other is by sending a message or something. A Xamarin.Forms project also comes with a native project. In this native Xamarin.Android project I try to retrieve inside the MainActivity.cs the button that exists within the main project by using (in WatchScreen.xaml this button exists and in WatchScreen.xaml.cs I have a method that gives this button back).
Method in WatchScreen.xaml.cs that gives button back:
public Button GetSendButtonFromWearableUI() => btnSendMessage;
In MainActivity.cs I get this method by using:
Button button = (App.Current.MainPage.Navigation.NavigationStack.LastOrDefault() as WatchScreen)
.GetSendButtonFromWearableUI();
Whenever I click on the button by doing this:
button.Clicked += delegate
{
SendData();
};
Some data should be sent from MainActivity.cs and catched by HomePage.xaml and displayed on it. I tried several approaches but I didn't succeed in achieving what needs to happen.. Therefore, I'm wondering if you guys could help me out with this and would be much appreciated.
In the meantime I've been investigating this issue and came up with a solution. Follow steps below to get the same result. To make this solution work I've combined the Wearable Data Layer API from Google and MessagingCenter from Microsoft.
Also the example below shows only the communication from the smartwatch to the smartphone. In order to reverse processes you can put the send button on the HomePage instead of the smartwatch screen and make sure to subscribe to the correct messages.
One last note: keep in mind that code used below from Google is deprecated but it still works...
References used to make this work:
Syncing Data Between Wearable and Handheld Devices Using Xamarin in Android
Installed dependencies on the Xamarin.Android project within Xamarin.Forms project:
Xamarin.Android.Support.v4
Xamarin.GooglePlayServices.Base
Xamarin.GooglePlayServices.Wearable
MessageKeys.cs
This class is used to declare message keys that are being used to send and receive messages between devices.
public class MessageKeys
{
public const string Smartwatch = "Smartwatch";
public const string Smartphone = "Smartphone";
}
Xamarin.Forms (Base project) - App.xaml.cs
In the App.xaml.cs, as pointed out earlier, I'm making sure the wearable UI displays WatchScreen.xaml and any other devices display regular Android UI -> HomePage.xaml.
Xamarin.Forms (Base project) - WatchScreen.xaml.cs
Send message from Wearable device to Android smartphone.
private void btnSendMessage_Clicked(object sender, EventArgs e)
{
MessagingCenter.Send(Xamarin.Forms.Application.Current, MessageKeys.Smartwatch);
}
Xamarin.Forms (Base project) - HomePage.xaml.cs
public HomePage()
{
InitializeComponent();
MessagingCenter.Subscribe<Xamarin.Forms.Application>(Xamarin.Forms.Application.Current, MessageKeys.Smartphone, (sender) =>
{
DisplayAlert("Message", "Wearable message received!", "OK");
});
}
Xamarin.Forms (Native Android Project) - MainActivity.cs
Within MainActivity.cs I implement the following interfaces:
public class MainActivity : WearableActivity, DataClient.IOnDataChangedListener,
GoogleApiClient.IConnectionCallbacks, GoogleApiClient.IOnConnectionFailedListener
Variables:
private GoogleApiClient client;
const string syncPath = "/[project name]/[subdirectory for watch]";
Internal class 'MessageReceiver' for receiving broadcast messages:
[BroadcastReceiver]
public class MessageReciever : BroadcastReceiver
{
MainActivity main;
public MessageReciever() { }
public MessageReciever(MainActivity owner) { this.main = owner; }
public override void OnReceive(Context context, Intent intent)
{
main.ProcessMessage(intent);
}
}
Registering receiver (to receive through Wearable Data Layer API), creating Google Client and Subscribing to smartwatch message (to retrieve message through MessagingCenter)
protected override void OnCreate(Bundle bundle)
{
IntentFilter filter = new IntentFilter(Intent.ActionSend);
MessageReciever receiver = new MessageReciever(this);
LocalBroadcastManager.GetInstance(this).RegisterReceiver(receiver, filter);
client = new GoogleApiClient.Builder(this, this, this)
.AddApi(WearableClass.Api)
.Build();
MessagingCenter.Subscribe<Xamarin.Forms.Application>(Xamarin.Forms.Application.Current, MessageKeys.Smartwatch, (sender) =>
{
SendData();
});
}
ProcessMessage method: sends received message from wearable to smartphone
public void ProcessMessage(Intent intent)
{
// For now I'm not sending the payload...
string message = intent.GetStringExtra("WearMessage");
MessagingCenter.Send(Xamarin.Forms.Application.Current, MessageKeys.Smartphone);
}
SendData(), OnStart(), OnStop(), OnDataChanged (didn't do anything with this part, because this is to receive messages outside the project and I don't need it for now), OnConnected(), OnConnectionSuspended(), OnConnectionFailed():
See the reference to see what code has been used, since code is exactly the same... P.S.: one thing for SendData has been changed. If you want to keep sending data, remove 'client.Disconenct()' from finally after the try and catch block.
Xamarin.Forms (Native Android Project) - WearableService inherits from WearableListenerService:
WearableService is a new class and created within the native project. Also for this part see the reference, because it's the exact same code being used within my project.
To get an overall overview of what's happening, I've visualized this in the diagram below: (example shows how communication works from smartwatch to smartphone)
If you want to communicate from smartphone to smartwatch, you could do something like this:
That's it guys. Now you will receive messages within the same application using the Wearable Data Layer API and MessagingCenter. Instead of having separate projects, we just use separate UIs to make this happen...

Minecraft Bukkit Server

I have created my own Craft Bukkit Minecraft server, and have everything almost set up but have run into a problem. You see, I wish for the server to automatically say something like this every 45 seconds or so:
[Server] Remember to follow the rules! (ETC.)
But I am not sure how to do it. I think I'll require a script, but I have no idea how I'd go about writing it.
Thanks for any help.
If you are looking to make your own plugin you can do a scheduler task every X time and Bukkit.broadcastMessage.
Example:
#Override
public void onEnable() {
new BukkitRunnable() {
#Override
public void run() {
Bukkit.broadcastMessage("[Server] This is the message.");
}
}.runTaskTimer(this, 20, 20*60*10); // 20*60*10 = 10 minutes
}
But if you want a already coded plugin you can download it from spigotmc.org
https://www.spigotmc.org/search/31904533/?q=automessage&t=resource_update&o=relevance

Inferior behavior of XSockets under Mono compared to MS.NET

Given
I am using XSockets 3.0.6 which I think is the latest stable version. Under MS.NET the behavior is as expected. On Ubuntu 14.04 and Mono 3.6.1 though the server has some kind of delays before sending messages to clients.
Problem
On MS.NET when I type a string in the client and send it, all clients are immediately notified. On Mono though message is received by the server and clients were not notified immediately. With only 1 message I waited for 5 minutes and clients were still not notified. When messages become 5-6 then all clients become notified about all messages at once. It seems like the server uses some kind of buffering but conditionally - depending on the .NET runtime, which is very strange.
Question
Am I doing something wrong? How to change the code so that all clients are immediately notified as in MS.NET?
Code
I followed (and slightly modified) the quick start example as follows...
Server
Initialization
using (var container = Composable.GetExport<IXSocketServerContainer>())
{
container.StartServers();
foreach (var server in container.Servers)
{
Console.WriteLine(server.ConfigurationSetting.Endpoint);
}
Console.Write("Started! Hit 'Enter' to quit.");
Console.ReadLine();
container.StopServers();
}
Custom controller
public class CustomController : XSocketController
{
public override void OnMessage(ITextArgs textArgs)
{
Console.WriteLine ("No delay = {0}", this.Socket.Socket.NoDelay);
if (!this.Socket.Socket.NoDelay)
{
Socket.Socket.NoDelay = true;
}
Console.WriteLine("Received {0} about {1}.", textArgs.data, textArgs.#event);
this.SendToAll(textArgs);
}
}
Client
var client = new XSocketClient("ws://127.0.0.1:4502/CustomController", "*");
client.OnOpen += (sender, eventArgs) => System.Console.WriteLine("OPEN");
client.Bind("foo", message => System.Console.WriteLine(message.data));
Thread.Sleep(1000);
client.Open();
string input;
System.Console.WriteLine("Type 'quit' to quit and any other string to send a message:");
do
{
input = System.Console.ReadLine();
if (input != "quit")
{
client.Send(input, "foo");
}
} while (input != "quit");
I experienced this my self when running XSockets on a raspberry pi.
After some investigation I realized that it had to do with the fact that the pi is single core and that internal queue did not send the message out until 5 messages was sent in.... Then all messages was sent out.
How many cores does your computer have ?
This issue is resolved in 4.0 (in alpha right now)
Edit: I have only had this issue on single core machines with Mono, on my Mac Book Air everything works great on Mono
It looks that the Naggle Algorithm is not disabled in XSockets. In System.Net.Sockets you can disable Naggle algorithm by setting Socket.NoDelay property to true.
I'm not familiar with XSockets, but if you can get underlying System.Net.Sockets.Socket class from XSockets, you can set this property to true and avoid the sending delay.

Play Frame work 2.2 How Concurrent execution works

Recently, we started to work with play 2.2. Previously we were working with play 2.1.3.
In play 2.2 it says Akka.future and async methods are seen as deprecated. Also when we tried to run below piece of code fetchSample() through a loop, it took more time to complete in play 2.2.
So how can we replace the below deprecated code with the latest one?
private static Promise<SampleDBResponseBean> fetchSample(
final Document sampleDoc) throws Exception {
Promise<SampleBean> promiseOfSampleJson = Akka.future(
new Callable<SampleBean>() {
public SampleBean call() throws Exception
{
return doSomeCalc(sampleDoc);
}
});
}
private Result getAsyncResult(final SampleResponseBean sampleDbResponseBean) {
List<F.Promise<? extends SampleDBResponseBean>> promiseList = sampleDbResponseBean
.getSampleHelperList();
Promise<List<SampleDBResponseBean>> promiseJsonObjLists = Promise
.sequence(promiseList);
return async(
promiseJsonObjLists.map(
new Function<List<SampleDBResponseBean>, Result>() {
public Result apply(List<SampleDBResponseBean> sampleList) {
SampleResponseBean sampleResponseBean = new SampleResponseBean();
sampleResponseBean.setStatus("success");
sampleResponseBean.setSampleList(sampleList);
JsonNode jsNodeResponse = Json.toJson(sampleResponseBean);
return ok(jsNodeResponse);
}
}));
}
I had searched a lot of places not seeing any solution. The problem effects our code performance when comparing to 2.1.3.
Any ideas how can we implement the deprecated methods for the above 2 methods in play 2.2?
As pointed out in the migration docs:
http://www.playframework.com/documentation/2.2.x/Migration22
You want to use Promise.promise. This is also described in the documentation:
http://www.playframework.com/documentation/2.2.x/JavaAsync
And of course in the API docs:
http://www.playframework.com/documentation/2.2.x/api/java/play/libs/F.Promise.html#promise(play.libs.F.Function0)
One of the really nice things about Play 2.2 Java promises is now you can control exactly which execution context the code runs in, so you can create your own execution context, or get one from Akka, and so control exactly how many, in your case, concurrent DB operations are run across the whole app at the same time.

test if jms listener is working

i want to test if the JMS listener is working !
to do that i want to test if the Queue size do not change for more than 5 seconds that means that the listener is not working
what should i add to my code please
try {
if ((msgIdMap.contains(tm.getJMSMessageID())) || !(message instanceof TextMessage)) {
System.out.println("\tListener not working !");
} else {
process((TextMessage) message);
}
If the listener is designed, coded and configured correctly it should be working unless there's a problem with the provider. If there is a problem with the provider, the client portion of the provider should detect it and call your ExceptionListener, if it is defined.
So, I would provide an ExceptionListener, by having your class implement the ExceptionListener:
public class MyJMSClass implements javax.jms.ExceptionListener {
then set the listener on the connection to this class:
connection.setExceptionListener(this);
then provide the recovery code:
public void onException(JMSException jmse) {
log.error("JMS exception has occured.. ", jmse);
// handle exception appropriately, perhaps by attempting to reconnect
}