If you had crashes with 0.5.2 try 0.6.0 and let me know if that has resolved issues. You should be able to open maps in packaged games with components whether your server is up or not. The only potentially unhandled use case is when you open a map to a server that is up and you swap map after the server status changes (e.g. becomes unreachable/goes down). If you have this use case you can use the workaround of setting bAsyncQuitDisconnect to false in your components (https://github.com//socketio-client-ue4/blob/master/Source/SocketIOClient/Public/SocketIOClientComponent.h#L54) which will synchronize your disconnects. If you have a lot of components it will add about ~ 1sec per component delay.
@
Thank you for putting out this fix so fast! I can confirm that my issues appear to be gone; the editor is no longer crashing nearly as much and switching levels in the packaged project appears to be working now. I still feel like I’m running into issue #44 though. I can switch from my first level where there are seven SocketIO components connected to my server, emit a message read by the server, read a response, and switch. When I switch, the components all disconnect and I can load the second level.
However, when this second level finishes it switches back to the first one and crashes in the packaged project. It sends a lot of messages back and forth to the server and has about 11 SocketIO components. These are all showing as disconnected when I log it in the server, but the first level can’t open up again. This error is only present in the packaged version. When I switch every component to disable asynchronous switching, this works properly in both the editor and the packaged game.
Obviously, this can lead to some load times that are a lot longer than they need to be. Any idea why this is happening or how to fix it? I’m certain that the server is staying completely accessible the whole time.
I believe “rooms” are different than namespaces. Some of the research I was doing yesterday suggested that namespaces are predefined, and rooms can be created dynamically.
I was having issues trying to connect to namespaces which were not yet created, which makes sense if they must be pre-defined.
I think this is related to the fact that the components don’t release all of their memory immediately in the asynchronous case. This then gets caught in UE4’s CanaryFail (related but not the same issue: answerhub) which is meant to catch garbage collection memory leaks. My understanding is that the system is not aware that another thread will release the memory when it is complete thus considers this a leak. The solution here would be to have the allocation cycle on something that survives world/level transitions (stack? plugin?).
For some reason the pooling of garbage collected objects are different in the editor vs packaged and this is why I think we’re getting the situation we have.
One potential solution I can think of is using plugin scoped memory allocation. I was experimenting with it earlier and there are some extra functions ready to try it out: https://github.com//socketio-client-ue4/blob/master/Source/SocketIOClient/Public/SocketIOClient.h#L36 but after I found a way to encapsulate the memory within the component I considered that cleaner and I didn’t pursue it further. With the packaging bug it may be that plugin scoping the memory would be appropriate after all.
Glancing over the source api again, it doesn’t look like the C++ client has anything setup for room use. Do you have javascript examples for socket.io client and server usage? Seeing this used in javascript could help inform how it’s supposed to look like in C++.
Ah, that’s really interesting. I’m working entirely with blueprints right now and would like to stick to working that way; do you think there’s a way for me to make use of this package scoping?
I’ll likely need to branch it and try a few things to see if it fixes it. Might be a bit before I get time for socketio plugin pass again. In meantime consider using the async disconnect toggle off.
so I’ve tried to get socket.io to work with my unreal project for actually several months now. And sometimes it kind of works but never really, so I very much hope that you guys can help me!
I have UE 4.15.2. and socket.io v0.6.0, those should be the up-to-date versions.
I’ve added the socket.io plugin directly to the engine, because when I added it to the project itself, the packaged project wouldn’t even start.
As long as I only connect to a socket.io client, everything still works fine. But once I try to emit an event, the editor freezes and crashes. It still emits the event though, because I can see that it works. If I package the project like that, it simply won’t emit the event.
So I don’t know what to do here. Best would be, if wouldn’t crash in the editor and if it would work in the packaged project. But I’m happy with everything just working in the packaged project, I can deal with a frozen editor.
What platform is this for? Windows is the only one that has functioning static libs atm. If it is windows, do you have a minimal reproducible project you can share or logs of the crash?
v0.6.0 should be fairly solid and I haven’t yet encountered what you describe so any info you can provide will greatly help.
Yes it’s for windows - win64. I’ll make a small project and see if I can reproduce the error, but I can share some logs now!
Since the crashes only happen, once I start emitting, I assume it has to do something with socket.io.
I’ll need more than this, looking forward to the example project. From the error though its pointing to an unbound function (I’m guessing some callback is null).
Are you emitting in blueprint? if so are you emitting with callback or just regular emit? (consider showing your emit graph)
so I just tried to add it to the first-person-example-project and the same happens. It crashes on emitting. I use a regular emit.
I’ll add a screenshot of the blueprint.
Something I forgot to say, I am not sure the connection is properly established.
Because if I check if it is connected, it returns that it isn’t. Here’s the blueprint, and it prints not connected and doesn’t emit anything.
Note that the above graph may not be doing what you want it to do. The act of connecting is multi-threaded and asynchronous, meaning that the function to connect returns before a connection is established. In your graph you try to emit right after calling connect, but when that call happens its almost guaranteed to not be connected. Typically if you want something to emit on begin play, after you’ve connected, you do this in the On Connected event dispatch found on your SocketIOClient component. That way you can be sure you’ve connected to your service before you make the emit call. Since you’re also emitting to a specified namespace, consider using the On Socked Namespace Connected instead, though from your log it appears you never connect to the /events namespace (check your server code).
That said the plugin should never cause a crash, and emits should be queued up and emitted whenever a connection is established/reestablished so I’ll try to replicate this issue on my next plugin pass and make sure that base is covered. Keep me posted if changing your emit to happen on connection solves your crashes though, as this is just an educated guess at this stage.
The problem with the crash on emitting persists.
I don’t have any crashes if the server raises an exception after handling the event, which is really weird. As soon as the server responds to my request, everything crashes. I am not using an emit with callback. The exception suppresses any responses, therefore unreal engine doesn’t crash. Naturally this is not a solution.
when I emit on connected it doesn’t change anything and emitting on socket namespace connected just doesn’t send the event - because the client connects to the correct namespace only on emitting.
I’ve found that after an “Open Level” node, the client socket disconnect and loses the session with the server.
This isn’t a problem after a login procedure because, for example, I am able to re-inject the login again via the “Option String”, but later if I made a match vs another player with a room, then that room is destroyed after disconnection.
Is it possible to not disconnect the client after “Open Level”? Or at least, if it’s not possible, connect to the previous session with the old Session ID?
Below you can find the server log: every disconnection here is caused by changing level.
hi @, thanks for awesome plugin. I have a question. Can I do live stream with this plugin? I mean I want to show gameplay on a web page. you can think like twitch.
You can pipe any data you want through the sockets, including video so there’s nothing stopping your there. The caveat is that socket.io in this implementation uses websockets which are based on TCP. This means that when some data does get dropped it will wait until that lost data re-transmitted and received before continuing which may not be the ideal response in the edge cases.
That said many modern streaming services do use TCP over port 80 with a buffer cache system and the streams are typically delayed up to ~20 seconds for both encoding purposes and to ensure a smooth overall experience.
The usual rule with TCP vs UDP is can you can accept 1-5 sec delay spikes in worst case scenarios? In this use case I believe that is ok and spikes can be mitigated with the aforementioned buffered cache.