SignalR Core - Error: Websocket closed with status code: 1006 - mongodb

I use SignalR in an Angular app. When I destroy component in Angular I also want to stop connection to the hub. I use the command:
this.hubConnection.stop();
But I get an error in Chrome console:
Websocket closed with status code: 1006
In Edge: ERROR Error: Uncaught (in promise): Error: Invocation canceled due to connection being closed. Error: Invocation canceled due to connection being closed.
It actually works and connection has been stopped, but I would like to know why I get the error.
This is how I start the hub:
this.hubConnection = new HubConnectionBuilder()
.withUrl("/matchHub")
.build();
this.hubConnection.on("MatchUpdate", (match: Match) => {
// some magic
})
this.hubConnection
.start()
.then(() => {
this.hubConnection.invoke("SendUpdates");
});
EDIT
I finally find the issue. Its caused by change streams from Mongo. If I remove the code from SendUpdates() method then OnDisconnected is triggered.
public class MatchHub : Hub
{
private readonly IMatchManager matchManager;
public MatchHub(IMatchManager matchManager)
{
this.matchManager = matchManager;
}
public async Task SendUpdates() {
using (var changeStream = matchManager.GetChangeStream()) {
while (changeStream.MoveNext()) {
var changeStreamDocument = changeStream.Current.FullDocument;
if (changeStreamDocument == null) {
changeStreamDocument = BsonSerializer.Deserialize<Match>(changeStream.Current.DocumentKey);
}
await Clients.Caller.SendAsync("MatchUpdate", changeStreamDocument);
}
}
}
public override async Task OnDisconnectedAsync(Exception exception)
{
await base.OnDisconnectedAsync(exception);
}
}
Method GetChangeStream from the manager.
ChangeStreamOptions options = new ChangeStreamOptions() { FullDocument = ChangeStreamFullDocumentOption.UpdateLookup };
var watch = mongoDb.Matches.Watch(options).ToEnumerable().GetEnumerator();
return watch;
But I don't know how to fix it.

This can be for many reasons but i think it is most likely this one:
I think this is because of how the server is handling the connected / disconnected events. I can't say for sure but the connection closing needs to handled correctly on the server also with code. Try overriding the built in On Connected /Disconnected methods on the server and see. My assumption only is that you're closing it but the server isn't closing properly and therefore not relaying the proper closed response.
found as a comment at : getting the reason why websockets closed with close code 1006
Where you don't need to change the connection/disconection because evrything works fine. But as an answer this one is the most likely.

It throws error because the callback doesn't get clear properly.
And it is caused by the return data from websocket.
normally it should return like
However, for some reason it might return something like
the very last response breaking into 2 pieces
And that causes the issue.
I don't think there is a way to bypass this without changing the source code.
I reported this on github repo as well at here
It turns out that I can just utilize invocation response to notify client to stop the hub. So it doesn't trigger racing issue.

Related

Azure Mobile Services for Xamarin Forms - Conflict Resolution

I'm supporting a production Xamarin Forms app with offline sync feature implemented using Azure Mobile Services.
We have a lot of production issues related to users losing data or general instability that goes away if the reinstall the app. After having a look through, I think the issues are around how the conflict resolution is handled in the app.
For every entity that tries to sync we handle MobileServicePushFailedException and then traverse through the errors returned and take action.
catch (MobileServicePushFailedException ex)
{
foreach (var error in ex.PushResult.Errors) // These are MobileServiceTableOpearationErrors
{
var status = error.Status; // HttpStatus code returned
// Take Action based on this status
// If its 409 or 412, we go in to conflict resolving and tries to decide whether the client or server version wins
}
}
The conflict resolving seems too custom to me and I'm checking to see whether there are general guidelines.
For example, we seem to be getting empty values for 'CreatedAt' & 'UpdatedAt' timestamps for local and server versions of the entities returned, which is weird.
var serverItem = error.Result;
var clientItem = error.Item;
// sometimes serverItem.UpdatedAt or clientItem.UpdatedAt is NULL. Since we use these 2 fields to determine who wins, we are stumped here
If anyone can point me to some guideline or sample code on how these conflicts should be generally handled using information from the MobileServiceTableOperationError, that will be highly appreciated
I came across the following code snippet from the following doc.
// Simple error/conflict handling.
if (syncErrors != null)
{
foreach (var error in syncErrors)
{
if (error.OperationKind == MobileServiceTableOperationKind.Update && error.Result != null)
{
//Update failed, reverting to server's copy.
await error.CancelAndUpdateItemAsync(error.Result);
}
else
{
// Discard local change.
await error.CancelAndDiscardItemAsync();
}
Debug.WriteLine(#"Error executing sync operation. Item: {0} ({1}). Operation discarded.",
error.TableName, error.Item["id"]);
}
}
Surfacing conflicts to the UI I found in this doc
private async Task ResolveConflict(TodoItem localItem, TodoItem serverItem)
{
//Ask user to choose the resolution between versions
MessageDialog msgDialog = new MessageDialog(
String.Format("Server Text: \"{0}\" \nLocal Text: \"{1}\"\n",
serverItem.Text, localItem.Text),
"CONFLICT DETECTED - Select a resolution:");
UICommand localBtn = new UICommand("Commit Local Text");
UICommand ServerBtn = new UICommand("Leave Server Text");
msgDialog.Commands.Add(localBtn);
msgDialog.Commands.Add(ServerBtn);
localBtn.Invoked = async (IUICommand command) =>
{
// To resolve the conflict, update the version of the item being committed. Otherwise, you will keep
// catching a MobileServicePreConditionFailedException.
localItem.Version = serverItem.Version;
// Updating recursively here just in case another change happened while the user was making a decision
UpdateToDoItem(localItem);
};
ServerBtn.Invoked = async (IUICommand command) =>
{
RefreshTodoItems();
};
await msgDialog.ShowAsync();
}
I hope this helps provide some direction. Although the Azure Mobile docs have been deprecated, the SDK hasn't changed and should still be relevant. If this doesn't help, let me know what you're using for a backend store.

Unity3D Network ReadMessage

How to check the ERROR if the client is trying to connect to a absent server?
my code!
//Server
void Start () {
NetworkServer.Listen(13044);
}
//Client
NetworkClient thisclient = new NetworkClient ();
thisclient.Connect ("127.0.0.1", 13044);
thisclient.RegisterHandler(MsgType.Error, errortest);
thisclient.RegisterHandler (MsgType.Disconnect, dctest);
void errortest(NetworkMessage netMsg){
var errorMsg = netMsg.ReadMessage<ErrorMessage>();
Debug.Log("Error:" + errorMsg.errorCode);}
void dctest(NetworkMessage netMsg){
//if I run the client while the server is not present, its goes here instead of errortest
}
You are using ReadMessage with ErrorMessage, but ErrorMessage is only valid in Error messages (OnError).
Your dctest function is triggered on disconnection, not on error.
Disconnect is a special MsgType (see https://docs.unity3d.com/ScriptReference/Networking.MsgType.html) that (if I remember) doesn't contain any data.
So to answer your question : you already have the result. Everything is in netMsg.
https://docs.unity3d.com/Manual/UNetMessages.html
The ReadMessage function is mostly used with your own NetworkMessages, when you wand to send/read custom data.

EntityFrameworkCore, trying to execute raw sql query but get error: "The connection was not closed. The connection's current state is open."

I need to run a raw sql query, but I'm getting an error when I try to open the connection to the database. "The connection was not closed. The connection's current state is open."
_loginValidator and _contactService are passed into the controller through DI:
services.AddScoped<ILoginValidator, LoginValidator>();
services.AddScoped<IContactService, ContactService>();
The two lines below are in an action function of the controller. If I switch the two lines, the error goes away...:
var validationErrors = _loginValidator.Validate(id, "");
var user = _contactService.GetContact(id);
Here is _loginValidator.Validate. If I comment out the second line, the error goes away...:
public LoginValidationResult Validate(int userId, string encryptedPassword)
{
var vr = new LoginValidationResult();
var user = _context.Users.Include(u => u.LoginUserQuestionAnswers).FirstOrDefault(u => u.Id == userId);
//...
}
Here is _contactService.GetContact. This is where I get the error:
public ContactDto GetContact(int id)
{
var conn = _context.Database.GetDbConnection();
//ERROR HERE!!!
conn.Open();
//work on conn, for example: ExecuteReader
conn.Close();
}
Notes:
If I comment out the _context line in the Validate(...) function, I do not get the error.
If I switch the two lines I listed in the action function, I do not get the error.
I think the problem is that EntityCore is not closing the connection after I finish using it in _loginValidator.Validate(...)
Anyone know how I can deal with this problem?
DB Connection is an unmanaged resource and you need to close it yourself. The best practice is to use a using statement for your DB connections.
See these links:
http://stackoverflow.com/questions/35077000/entity-framework-7-get-database-time
https://msdn.microsoft.com/en-us/data/dn456849.aspx
The connection being left open after the FirstOrDefault query is a bug. I filed https://github.com/aspnet/EntityFramework/issues/6581 for it and we just triaged it for the 1.0.2 release.
To workaround the bug for now I think you can check if the connection is already open and, if so, don't try to open it again.

Provide UserName<553> message in quick

I have created an application for FIX transactions using QuickFIX c++ API. The application is connecting to the server but the server sends "Provide UserName<553>" message. I looked for and result and found that i need to add username and password to the toAdmin method created this following code to in order to achieve that
void Application::toAdmin( FIX::Message& message, const FIX::SessionID& sessionID)
{
if (FIX::MsgType_Logon == message.getHeader().getField(FIX::FIELD::MsgType))
{
FIX44::Logon& logon_message = dynamic_cast<FIX44::Logon&>(message);
logon_message.setField(FIX::Username("my_username"));
logon_message.setField(FIX::Password("my_password"));
}
}
But then it throws and Exception. Please suggest what to do
remove this line and exception is handled
FIX44::Logon& logon_message = dynamic_cast<FIX44::Logon&>(message);
after that Put it
message.setField(FIX::Username("my_username"));
```````
message.setField(FIX::Password("my_password"));

Nodejs: How to catch exception in net.createServer.on("data",...)?

I've got a standard socket-server (NO HTTP) setup as follows (contrived):
var server = net.createServer(function(c) { //'connection' listener
c.on('data', function(data) {
//do stuff here
//some stuff can result in an exception that isn't caught anywhere downstream,
//so it bubbles up. I try to catch it here.
//this is the same problem as just trying to catch this:
throw new Error("catch me if you can");
});
}).listen(8124, function() { //'listening' listener
console.log('socket server started on port 8124,');
});
Now the thing is I've got some code throwing errors that aren't catched at all, crashing the server. As a last measure I'd like to catch them on this level, but anything I've tried fails.
server.on("error",....)
c.on("error",...)
Perhaps I need to get to the socket instead of c (the connection), although I'm not sure how.
I'm on Node 0.6.9
Thanks.
process.on('uncaughtException',function(err){
console.log('something terrible happened..')
})
You should catch the Exceptions yourself. There is no event on either connection or server objects which would allow you to handle exception the way you described. You should add exception handling logic into your event handlers to avoid server crash like this:
c.on('data', function(data) {
try {
// even handling code
}
catch(exception) {
// exception handling code
}