Friday, August 12, 2016

Part 2: Multiplayer WebSocket Game server written in C using libuv & libwebsockets & Cocos2d-x-HTML5

Assuming the compilation of the server went as expected and the exe file did created.
You can start it clicking F5 in Visual Studio , the server will be listening for incoming requests
On port 7681.

Few Notes About the Client Server Architecture i use it this tutorial .
As mentioned in PART 1 of this tutorial , the example here going to implement the Authoritative server ,
In short what it means is the server will not send on each client game loop verification instead of it will send to the client the game status as played in the server , and the client will current the moves according to the server status or just keep with the game flow if its vaild . the client will use something called : client prediction , what this means in short is that the client will send to the server the game info that happens , but it will not wait for the verification for each step , it will just verify that the steps before the current step are done right . ( meter of milliseconds ) .

The source code :
ws_cococs_server_main.c 
This file will initialize the libuv framework and the libwebsockets
The libwebsockets will use the libuv event loop and other services and will take command on the entire server .




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include "game_handler.h"
#include <uv.h>

int debug_level = 7;
struct lws_context *context;
#define MAX_ECHO_PAYLOAD 1024
static uv_timer_t timer_handle;
static int timer_cb_called;
static uv_once_t once = UV_ONCE_INIT;
static int once_cb_called = 0;
static int repeat_close_cb_called = 0;
static int once_close_cb_called = 0;
static int repeat_cb_called = 0;
static struct lws_protocols protocols[] = {  
 {
  "wsapi",
  callback_wsapi,
  sizeof(struct per_session_data__apigataway),
  MAX_ECHO_PAYLOAD,
 },
  
 { NULL, NULL, 0, 0 } /* terminator */
};
void signal_cb(uv_signal_t *watcher, int signum)
{
 lwsl_err("Signal %d caught, exiting...\n", watcher->signum);
 switch (watcher->signum) {
 case SIGTERM:
 case SIGINT:
  break;
 default:
  signal(SIGABRT, SIG_DFL);
  abort();
  break;
 }
 lws_libuv_stop(context);
}

int main(int argc, char **argv)
{
 struct lws_context_creation_info info;
 const char *iface = NULL;
 int opts = 0;
  uv_loop_t* loop = NULL;
 /* tell the library what debug level to emit and to send it to syslog */
 lws_set_log_level(debug_level, lwsl_emit_syslog);
 lwsl_notice("About to start server\n");

    memset(&info, 0, sizeof info);
 info.port = 7681;
 info.iface = NULL;
 info.protocols = protocols;
 info.extensions = NULL;
 info.ssl_cert_filepath = NULL;
 info.ssl_private_key_filepath = NULL;
 info.gid = -1;
 info.uid = -1;
 info.max_http_header_pool = 1;
 info.timeout_secs = 5;
 info.options = opts | LWS_SERVER_OPTION_LIBUV;

 context = lws_create_context(&info);
 if (context == NULL) {
  lwsl_err("libwebsocket init failed\n");
  return -1;
 }

 lws_uv_sigint_cfg(context, 1, signal_cb);
 if (lws_uv_initloop(context,NULL /*loop*/, 0)) {
  lwsl_err("lws_uv_initloop failed\n");

  goto bail;
 }

 lwsl_notice("server started\n");
 lws_libuv_run(context, 0);

bail:
 lws_context_destroy(context);
 lwsl_notice("server exited cleanly\n");


 return 0;
}

Lines 14 - 23:  libwebsockets part of it configuration we can define several protocols
Line 16: this is the uri which the client will call the web sockets request.
Line 17:callback_wsapi is the name of the main function which receive the client request.
Line 18:the size of the data structure which will hold the session data 
which means that each protocol can capture our request and process it
we are going to use only 1 protocol which process our web sockets requests
the HTTP hand shack authentication will be handled automatically by libwebsockets .
Lines 24 -35: callback which be called in case of context initialization failure . (line 68)
Lines 39 -84: configuration of libwebsockets
Line 50: server port
Line 60: configure libwebsockets to use libuv as its networking layer .

Continue to PART 3 server code
















No comments:

Post a Comment