void dslink_handshake_handle_ws(DSLink *link) { struct wslay_event_callbacks callbacks = { want_read_cb, want_write_cb, gen_mask_cb, NULL, NULL, NULL, recv_frame_cb }; wslay_event_context_ptr ptr; if (wslay_event_context_client_init(&ptr, &callbacks, link) != 0) { return; } link->_ws = ptr; dslink_event_loop_init(&link->loop, io_handler, link); dslink_event_loop_sched(&link->loop, ping_handler, link); dslink_event_loop_process(&link->loop); dslink_event_loop_free(&link->loop); wslay_event_context_free(ptr); link->_ws = NULL; }
WebSocketClient(int fd, struct wslay_event_callbacks *callbacks, const std::string& body) : fd_(fd), body_(body), body_off_(0), dev_urand_("/dev/urandom") { wslay_event_context_client_init(&ctx_, callbacks, this); }
static mrb_value mrb_wslay_event_context_client_init(mrb_state *mrb, mrb_value self) { mrb_value callbacks_obj; mrb_get_args(mrb, "o", &callbacks_obj); mrb_value recv_callback, send_callback, on_msg_recv_callback; recv_callback = mrb_iv_get(mrb, callbacks_obj, mrb_intern_lit(mrb, "@recv_callback")); if (mrb_type(recv_callback) != MRB_TT_PROC) { mrb_raise(mrb, E_ARGUMENT_ERROR, "recv_callback missing"); } send_callback = mrb_iv_get(mrb, callbacks_obj, mrb_intern_lit(mrb, "@send_callback")); if (mrb_type(send_callback) != MRB_TT_PROC) { mrb_raise(mrb, E_ARGUMENT_ERROR, "send_callback missing"); } on_msg_recv_callback = mrb_iv_get(mrb, callbacks_obj, mrb_intern_lit(mrb, "@on_msg_recv_callback")); if (mrb_type(on_msg_recv_callback) != MRB_TT_PROC) { mrb_raise(mrb, E_ARGUMENT_ERROR, "on_msg_recv_callback missing"); } mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "callbacks"), callbacks_obj); mrb_wslay_user_data *data = (mrb_wslay_user_data *) mrb_malloc(mrb, sizeof(mrb_wslay_user_data)); mrb_data_init(self, data, &mrb_wslay_user_data_type); data->mrb = mrb; data->recv_callback = recv_callback; data->send_callback = send_callback; data->on_msg_recv_callback = on_msg_recv_callback; struct wslay_event_callbacks client_callbacks = { mrb_wslay_event_recv_callback, mrb_wslay_event_send_callback, mrb_wslay_event_genmask_callback, NULL, NULL, NULL, mrb_wslay_event_on_msg_recv_callback }; int err = wslay_event_context_client_init(&data->ctx, &client_callbacks, data); if (err == WSLAY_ERR_NOMEM) { mrb_sys_fail(mrb, "wslay_event_context_client_init"); } else if (err != 0) { return MRB_WSLAY_ERROR(mrb_fixnum_value(err)); } return self; }
websocket_return_t websocket_client_open(websocket_t *client, char *host, char *port, char *path) { int fd = -1; int r = WEBSOCKET_SUCCESS; struct websocket_info_t *socket_data = NULL; struct sched_param ws_sparam; if (client == NULL || host == NULL || port == NULL || path == NULL) { WEBSOCKET_DEBUG("NULL parameter\n"); return WEBSOCKET_ALLOCATION_ERROR; } websocket_update_state(client, WEBSOCKET_RUN_CLIENT); //TODO : all TLS initializing code will be moved from example to here if (websocket_connect(client, host, port) != WEBSOCKET_SUCCESS) { r = WEBSOCKET_CONNECT_ERROR; goto EXIT_CLIENT_OPEN; } fd = client->fd; if (websocket_client_handshake(client, host, port, path) != WEBSOCKET_SUCCESS) { WEBSOCKET_DEBUG("fail to http handshake\n"); r = WEBSOCKET_HANDSHAKE_ERROR; goto EXIT_CLIENT_OPEN; } socket_data = malloc(sizeof(struct websocket_info_t)); if (socket_data == NULL) { WEBSOCKET_DEBUG("fail to allocate memory\n"); r = WEBSOCKET_ALLOCATION_ERROR; goto EXIT_CLIENT_OPEN; } memset(socket_data, 0, sizeof(struct websocket_info_t)); socket_data->data = client; if (wslay_event_context_client_init(&client->ctx, client->cb, socket_data) != WEBSOCKET_SUCCESS) { WEBSOCKET_DEBUG("fail to init websocket client context\n"); WEBSOCKET_FREE(socket_data); r = WEBSOCKET_INIT_ERROR; goto EXIT_CLIENT_OPEN; } WEBSOCKET_DEBUG("start websocket client handling thread\n"); if (pthread_attr_init(&client->thread_attr) != 0) { WEBSOCKET_DEBUG("fail to init pthread attribute\n"); r = WEBSOCKET_ALLOCATION_ERROR; goto EXIT_CLIENT_OPEN; } if (pthread_attr_setstacksize(&client->thread_attr, WEBSOCKET_STACKSIZE) != 0) { WEBSOCKET_DEBUG("fail to set stack size\n"); r = WEBSOCKET_ALLOCATION_ERROR; goto EXIT_CLIENT_OPEN; } ws_sparam.sched_priority = WEBSOCKET_PRI; if (pthread_attr_setschedparam(&client->thread_attr, &ws_sparam) != 0) { WEBSOCKET_DEBUG("fail to set priority\n"); r = WEBSOCKET_ALLOCATION_ERROR; goto EXIT_CLIENT_OPEN; } if (pthread_attr_setschedpolicy(&client->thread_attr, WEBSOCKET_SCHED_POLICY) != 0) { WEBSOCKET_DEBUG("fail to set scheduler policy\n"); r = WEBSOCKET_ALLOCATION_ERROR; goto EXIT_CLIENT_OPEN; } if (pthread_create(&client->thread_id, &client->thread_attr, (pthread_startroutine_t) websocket_handler, (pthread_addr_t) client) != 0) { WEBSOCKET_DEBUG("fail to create websocket client thread\n"); r = WEBSOCKET_ALLOCATION_ERROR; goto EXIT_CLIENT_OPEN; } if (pthread_setname_np(client->thread_id, "websocket client handler") != 0) { WEBSOCKET_DEBUG("fail to set thread name\n"); r = WEBSOCKET_ALLOCATION_ERROR; goto EXIT_CLIENT_OPEN; } if (pthread_detach(client->thread_id) != 0) { WEBSOCKET_DEBUG("fail to detach websocket handler thread\n"); r = WEBSOCKET_ALLOCATION_ERROR; goto EXIT_CLIENT_OPEN; } return r; EXIT_CLIENT_OPEN: WEBSOCKET_CLOSE(fd); if (client->ctx) { wslay_event_context_free(client->ctx); client->ctx = NULL; } websocket_update_state(client, WEBSOCKET_STOP); return r; }