Cocos2d-js WebSocket Server

I just wanted to share something that i’been working for a couple of weeks. I wanted to use a WebSocket Server that would be inside of a game. I build one in android with java and i had the intention to build other one in Objective C for IOS.

I didn’t like the idea of implementing the server twice, so, after some reading and testing i was able to implement a WebSocket Server with C++ using the Libwebsockets lib (already included with Cocos) and create also the JavaScript binding so it can be used in Cocos2d-js.

I made a four part blog with instructions about how to do use it:

The code is on GitHub:

https://github.com/carlgira/wsserver-cocos2djs

In GitHub you can find:

  • A precompiled server enabled version of libwebsockets for android and ios. (websockets.zip)
  • A C++ implementation of a WebSocketServer. (WebSocketServer.h, WebSocketServer.cpp)
  • A C++ JavaScript bindings for Cocos (jsb_websocketserver.h, jsb_websocketserver.cpp)
  • An android makefile to include libwebsocket in an android project (Android.mk)
  • A JavaScript app to start the Server an test it with some clients (app.js)
  • An additional web client to test the WebSocketServer app (test-server.html)

I hope someone find this useful.

Thanks!

5 Likes

Is there any way we can find the client readyState??

Ive tried implementing this in a turn based game and it went well…but if a client connects to a server and tries to call the socket.close() the app crashes leaving this error log…

D/libwebsockets( 4750): NOTICE: lws_context_destroy
D/WebSocketServer.cpp( 4750): Unhandled websocket event: 33
D/WebSocketServer.cpp( 4750): Unhandled websocket event: 30
D/WebSocketServer.cpp( 4750): Unhandled websocket event: 33
D/WebSocketServer.cpp( 4750): Unhandled websocket event: 30
D/WebSocketServer.cpp( 4750): Unhandled websocket event: 28
D/WebSocketServer.cpp( 4750): WebSocketServer thread exit, helper instance: 0xb9f11b10
D/WebSocket.cpp( 4750): WebSocket (0xb95a5360) onConnectionClosed ...
D/libwebsockets( 4750): NOTICE: lws_context_destroy
D/WebSocket.cpp( 4750): onConnectionClosed: WebSocket (0xb95a5360) was closed, no need to close it again!
D/WebSocket.cpp( 4750): WebSocket thread exit, helper instance: 0xb954f2a0
F/libc    ( 4750): Fatal signal 11 (SIGSEGV) at 0x00000004 (code=1), thread 4774 (Thread-290)
I/DEBUG   ( 1399): pid: 4750, tid: 4774, pkg name: org.cocos2dx.planetrummy_3_14
I/DEBUG   ( 1399): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   ( 1399): Build fingerprint: 'samsung/hlteuc/hlteatt:4.4.2/KOT49H/N900AUCUCMLG:user/release-keys'
I/DEBUG   ( 1399): Revision: '0'
I/DEBUG   ( 1399): pid: 4750, tid: 4774, name: Thread-290  >>> org.cocos2dx.planetrummy_3_14 <<<
I/DEBUG   ( 1399): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000004
W/NativeCrashListener( 1744): Couldn't find ProcessRecord for pid 1885955130
I/DEBUG   ( 1399):     eax 00000004  ebx 000000c6  ecx 00000004  edx 00000004
I/DEBUG   ( 1399): AM write failure (32 / Broken pipe)
I/DEBUG   ( 1399):     esi 00000e59  edi 00000000
I/DEBUG   ( 1399):     xcs 00000073  xds 0000007b  xes 0000007b  xfs 00000043  xss 0000007b
I/DEBUG   ( 1399):     eip 89cff966  ebp 1a226f2c  esp 1a226ee4  flags 00210246
I/DEBUG   ( 1399):
I/DEBUG   ( 1399): backtrace:
I/DEBUG   ( 1399):     #00  pc 000c6966  /system/lib/lib3btrans.so
I/DEBUG   ( 1399):     #01  pc 00023d0b  <unknown>
I/DEBUG   ( 1399):     #02  pc 000b2212  /system/lib/lib3btrans.so
I/DEBUG   ( 1399):     #03  pc 0010202f  [stack:4769]
I/DEBUG   ( 1399):     #04  pc 000aeea7  /system/lib/lib3btrans.so
I/DEBUG   ( 1399):     #05  pc 00a1132b  /data/app-lib/org.cocos2dx.planetrummy_3_14-2/libcocos2djs.so (cocos2d::network::WsServerThreadHelper::sendMessageToWebSocketServerThread(int, cocos2d::network::WsServerMessage*)+51)
I/DEBUG   ( 1399):     #06  pc 000ae88c  /system/lib/lib3btrans.so
I/DEBUG   ( 1399):     #07  pc ffffffff  <unknown>
I/DEBUG   ( 1399):     #08  pc 000fdb2c  /system/lib/lib3btrans.so
I/DEBUG   ( 1399):     #09  pc ffffffff  <unknown>
I/DEBUG   ( 1399):     #10  pc 0000dfff  [stack:4774]
I/DEBUG   ( 1399):     #11  pc 0018e6ea  /system/lib/lib3btrans.so
I/DEBUG   ( 1399):
I/DEBUG   ( 1399): stack:
I/DEBUG   ( 1399):          1a226ea4  00000000
I/DEBUG   ( 1399):          1a226ea8  00000000
I/DEBUG   ( 1399):          1a226eac  00000000
I/DEBUG   ( 1399):          1a226eb0  1a215030  [stack:4769]
I/DEBUG   ( 1399):          1a226eb4  0000000b
I/DEBUG   ( 1399):          1a226eb8  00000000
I/DEBUG   ( 1399):          1a226ebc  1a226edc  [stack:4774]
I/DEBUG   ( 1399):          1a226ec0  89dc71b1  /system/lib/lib3btrans.so
I/DEBUG   ( 1399):          1a226ec4  00000001
I/DEBUG   ( 1399):          1a226ec8  00000000
I/DEBUG   ( 1399):          1a226ecc  1a215030  [stack:4769]
I/DEBUG   ( 1399):          1a226ed0  d001429a
I/DEBUG   ( 1399):          1a226ed4  f7c7d001
I/DEBUG   ( 1399):          1a226ed8  1a215030  [stack:4769]
I/DEBUG   ( 1399):          1a226edc  1a226f2c  [stack:4774]
I/DEBUG   ( 1399):          1a226ee0  89d01fa7  /system/lib/lib3btrans.so
I/DEBUG   ( 1399):     #00  1a226ee4  18053d0c
I/DEBUG   ( 1399):          ........  ........
I/DEBUG   ( 1399):          ........  ........
I/DEBUG   ( 1399):     #02  1a226f34  1a215030  [stack:4769]
I/DEBUG   ( 1399):          ........  ........
D/BstCommandProcessor-Application( 1928): Application crash has been observed.
I/BootReceiver( 1744): Copying /data/tombstones/tombstone_03 to DropBox (SYSTEM_TOMBSTONE)
D/Zygote  ( 1401): Process 4750 terminated by signal (11)
D/dalvikvm( 1744): GC_CONCURRENT freed 1163K, 27% free 6883K/9348K, paused 1ms+2ms, total 17ms
D/dalvikvm( 1744): WAIT_FOR_CONCURRENT_GC blocked 11ms
I/dalvikvm-heap( 1744): Grow heap (frag case) to 6.940MB for 196620-byte allocation
W/InputDispatcher( 1744): channel '4ea2b82c org.cocos2dx.planetrummy_3_14/org.cocos2dx.javascript.AppActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x9
E/InputDispatcher( 1744): channel '4ea2b82c org.cocos2dx.planetrummy_3_14/org.cocos2dx.javascript.AppActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
D/dalvikvm( 1744): GC_FOR_ALLOC freed <1K, 26% free 7075K/9544K, paused 21ms, total 21ms
I/dalvikvm-heap( 1744): Grow heap (frag case) to 7.220MB for 294928-byte allocation
D/dalvikvm( 1744): WAIT_FOR_CONCURRENT_GC blocked 36ms
I/dalvikvm-heap( 1744): Grow heap (frag case) to 7.237MB for 16396-byte allocation
D/NsdService( 1744): stopMDnsDaemon
D/dalvikvm( 1744): GC_FOR_ALLOC freed 192K, 27% free 7187K/9836K, paused 9ms, total 9ms
D/MDnsDS  ( 1398): Stopping MDNSD
I/WindowState( 1744): WIN DEATH: Window{4ea5a14c u0 SurfaceView}
W/InputDispatcher( 1744): Attempted to unregister already unregistered input channel '4ea2b82c org.cocos2dx.planetrummy_3_14/org.cocos2dx.javascript.AppActivity (server)'
I/WindowState( 1744): WIN DEATH: Window{4ea2b82c u0 org.cocos2dx.planetrummy_3_14/org.cocos2dx.javascript.AppActivity}
I/ActivityManager( 1744): Process org.cocos2dx.planetrummy_3_14 (pid 4750) has died.
W/ActivityManager( 1744): Force removing ActivityRecord{4e9a161c u0 org.cocos2dx.planetrummy_3_14/org.cocos2dx.javascript.AppActivity t4}: app died, no saved state
D/dalvikvm( 1744): GC_FOR_ALLOC freed 110K, 28% free 7108K/9836K, paused 13ms, total 13ms
I/dalvikvm-heap( 1744): Grow heap (frag case) to 7.159MB for 196648-byte allocation
D/dalvikvm( 1744): GC_FOR_ALLOC freed 296K, 31% free 7004K/10032K, paused 12ms, total 12ms
D/GuidanceScreen( 1944): mBstOemFeatures === 2107393
I/StatsUtility( 1958): in StatsUtility constructor
I/StatsUtility( 1958): in doInBackground of StatsUtility
I/StatsUtility( 1958): DAU_TIMESTAMP = 1504066352558
D/ActivityManager( 1744): TopActivityInfo, pkgName: com.bluestacks.gamepophome activityName: com.bluestacks.gamepophome/com.uncube.launcher3.Launcher callingPackage:   bstSpecialAppKeyboardHandlingEnabled = false
D/ActivityManager( 1744): Showing guidance for pkgName: com.bluestacks.gamepophome
D/WindowManager( 1744): in computeScreenConfigurationLocked() -- hardKeyboardAvailable :true  mHardKeyboardAvailable :true   mHardKeyboardEnabled :true
D/GuidanceScreen( 1944): event === app_launch
D/GuidanceScreen( 1944): hiding guidance
D/GuidanceScreen( 1944): hardKeyboard = 1
D/GuidanceScreen( 1944): controllerType === Keyboard
D/GuidanceScreen( 1944): appName: Torque Launcher, currentPkg: com.bluestacks.gamepophome, event: app_launch, controller: Keyboard
D/GuidanceScreen( 1944): appName: Torque Launcher
D/com.uncube.accountMyAccountAppLaunchReceiver( 4790): onReceive
D/com.uncube.accountMyAccountAppLaunchReceiver( 4790): launchedPackage is com.bluestacks.gamepophome
D/com.uncube.accountMyAccountAppLaunchReceiver( 4790): return
D/GuidanceScreen( 1944): showing guidance for Torque Launcher as not recommended ad found
D/GuidanceScreen( 1944): guidance found for com.bluestacks.gamepophome
D/GuidanceScreen( 1944): showing guidance
D/GuidanceScreen( 1944): Not showing guidance for appmart or com.android.vending
D/Home.AppLaunchReceiver( 2038): *************************Received app launch broadcast
D/dalvikvm( 1744): GC_CONCURRENT freed 2155K, 36% free 6476K/10032K, paused 1ms+1ms, total 19ms

Is there any way to bypass this??

@carlgira hello need help…

I have also server / client tutorial to set up libwebsocktes server

@AbhyudaiRagh, did you fix this issue? I have the same problem now

Hi there, (i know its been a while).

The websocket server was very simple and it did not implement all possible callbacks, thats why the message “Unhandled websocket event:”

I will check it but i think is not that hard. Go to the “WebSocketServer.cpp” to the method onSocketCallback, and debug to identify for the event that is not been handled, add the condition using the corresponding flag (look for flag in https://libwebsockets.org/lws-api-doc-master/html/group__usercb.html) and according with the event add some logic. (i’m pretty sure you can copy and paste something of the already existing switch conditions)

Hii,
I just left this WebsocketServer class and created a websocket server side for android using java and implemented in my game.Im not that good at pragramming in c++.
Even though i’ll try doing the things as you said.
Thanks for the reply,