subscriber_t *websocket_subscriber_create(ngx_http_request_t *r, nchan_msg_id_t *msg_id) { nchan_request_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_nchan_module); DBG("create for req %p", r); full_subscriber_t *fsub; if((fsub = ngx_alloc(sizeof(*fsub), ngx_cycle->log)) == NULL) { ERR("Unable to allocate"); return NULL; } nchan_subscriber_init(&fsub->sub, &new_websocket_sub, r, msg_id); fsub->cln = NULL; fsub->ctx = ctx; fsub->ws_meta_subprotocol = 0; fsub->finalize_request = 0; fsub->holding = 0; fsub->shook_hands = 0; fsub->connected = 0; fsub->pinging = 0; fsub->closing = 0; ngx_memzero(&fsub->ping_ev, sizeof(fsub->ping_ev)); nchan_subscriber_init_timeout_timer(&fsub->sub, &fsub->timeout_ev); fsub->dequeue_handler = empty_handler; fsub->dequeue_handler_data = NULL; fsub->awaiting_destruction = 0; ngx_memzero(&fsub->closing_ev, sizeof(fsub->closing_ev)); #if nginx_version >= 1008000 fsub->closing_ev.cancelable = 1; #endif //what should the buffers look like? /* //mesage buf b->last_buf = 1; b->last_in_chain = 1; b->flush = 1; b->memory = 1; b->temporary = 0; */ if(fsub->sub.cf->pub.websocket) { fsub->publish_channel_id = nchan_get_channel_id(r, PUB, 0); } fsub->upstream_stuff = NULL; websocket_init_frame(&fsub->frame); //http request sudden close cleanup if((fsub->cln = ngx_http_cleanup_add(r, 0)) == NULL) { ERR("Unable to add request cleanup for websocket subscriber"); return NULL; } fsub->cln->data = fsub; fsub->cln->handler = (ngx_http_cleanup_pt )sudden_abort_handler; DBG("%p created for request %p", &fsub->sub, r); assert(ctx != NULL); ctx->sub = &fsub->sub; //gonna need this for recv ctx->subscriber_type = fsub->sub.name; #if NCHAN_SUBSCRIBER_LEAK_DEBUG subscriber_debug_add(&fsub->sub); #endif //send-frame buffer ctx->output_str_queue = ngx_palloc(r->pool, sizeof(*ctx->output_str_queue)); nchan_reuse_queue_init(ctx->output_str_queue, offsetof(framebuf_t, prev), offsetof(framebuf_t, next), framebuf_alloc, NULL, r->pool); //bufchain pool ctx->bcp = ngx_palloc(r->pool, sizeof(nchan_bufchain_pool_t)); nchan_bufchain_pool_init(ctx->bcp, r->pool); return &fsub->sub; }
subscriber_t *websocket_subscriber_create(ngx_http_request_t *r, nchan_msg_id_t *msg_id) { ngx_buf_t *b; nchan_loc_conf_t *cf = ngx_http_get_module_loc_conf(r, nchan_module); DBG("create for req %p", r); full_subscriber_t *fsub; if((fsub = ngx_alloc(sizeof(*fsub), ngx_cycle->log)) == NULL) { ERR("Unable to allocate"); return NULL; } ngx_memcpy(&fsub->sub, &new_websocket_sub, sizeof(new_websocket_sub)); fsub->request = r; fsub->cln = NULL; fsub->finalize_request = 0; fsub->holding = 0; fsub->shook_hands = 0; fsub->sub.cf = ngx_http_get_module_loc_conf(r, nchan_module); if(msg_id) { fsub->sub.last_msg_id.time = msg_id->time; fsub->sub.last_msg_id.tag = msg_id->tag; } ngx_memzero(&fsub->timeout_ev, sizeof(fsub->timeout_ev)); fsub->timeout_handler = empty_handler; fsub->timeout_handler_data = NULL; fsub->dequeue_handler = empty_handler; fsub->dequeue_handler_data = NULL; fsub->already_enqueued = 0; fsub->awaiting_destruction = 0; fsub->reserved = 0; //initialize reusable chains and bufs ngx_memzero(&fsub->hdr_buf, sizeof(fsub->hdr_buf)); ngx_memzero(&fsub->msg_buf, sizeof(fsub->msg_buf)); //space for frame header fsub->hdr_buf.start = ngx_pcalloc(r->pool, WEBSOCKET_FRAME_HEADER_MAX_LENGTH); fsub->hdr_chain.buf = &fsub->hdr_buf; fsub->hdr_chain.next = &fsub->msg_chain; fsub->msg_chain.buf = &fsub->msg_buf; fsub->msg_chain.next = NULL; //what should the buffers look like? b = &fsub->msg_buf; b->last_buf = 1; b->last_in_chain = 1; b->flush = 1; b->memory = 1; b->temporary = 0; if(cf->pub.websocket) { fsub->publish_channel_id = nchan_get_channel_id(r, PUB, 0); } websocket_init_frame(&fsub->frame); fsub->owner = memstore_slot(); //http request sudden close cleanup if((fsub->cln = ngx_http_cleanup_add(r, 0)) == NULL) { ERR("Unable to add request cleanup for websocket subscriber"); return NULL; } fsub->cln->data = fsub; fsub->cln->handler = (ngx_http_cleanup_pt )sudden_abort_handler; DBG("%p created for request %p", &fsub->sub, r); ngx_http_set_ctx(r, fsub, nchan_module); //gonna need this for recv return &fsub->sub; }