static ngx_int_t websocket_publish_callback(ngx_int_t status, nchan_channel_t *ch, full_subscriber_t *fsub) { time_t last_seen = 0; ngx_uint_t subscribers = 0; ngx_uint_t messages = 0; nchan_msg_id_t *msgid = NULL; ngx_http_request_t *r = fsub->sub.request; ngx_str_t *accept_header = NULL; ngx_buf_t *tmp_buf; nchan_buf_and_chain_t *bc = nchan_bufchain_pool_reserve(fsub->ctx->bcp, 1); if(ch) { subscribers = ch->subscribers; last_seen = ch->last_seen; messages = ch->messages; msgid = &ch->last_published_msg_id; } if(websocket_release(&fsub->sub, 0) == NGX_ABORT) { //zombie publisher //nothing more to do, we're finished here return NGX_OK; } switch(status) { case NCHAN_MESSAGE_QUEUED: case NCHAN_MESSAGE_RECEIVED: if(fsub->sub.cf->sub.websocket) { //don't reply with status info, this websocket is used for subscribing too, //so it should only be recieving messages return NGX_OK; } if(r->headers_in.accept) { accept_header = &r->headers_in.accept->value; } tmp_buf = nchan_channel_info_buf(accept_header, messages, subscribers, last_seen, msgid, NULL); ngx_memcpy(&bc->buf, tmp_buf, sizeof(*tmp_buf)); bc->buf.last_buf=1; nchan_output_filter(fsub->sub.request, websocket_frame_header_chain(fsub, WEBSOCKET_TEXT_LAST_FRAME_BYTE, ngx_buf_size((&bc->buf)), &bc->chain)); break; case NGX_ERROR: case NGX_HTTP_INTERNAL_SERVER_ERROR: assert(0); break; } return NGX_OK; }
static ngx_int_t websocket_publish_callback(ngx_int_t status, nchan_channel_t *ch, full_subscriber_t *fsub) { time_t last_seen = 0; ngx_uint_t subscribers = 0; ngx_uint_t messages = 0; ngx_http_request_t *r = fsub->request; ngx_str_t *accept_header = NULL; ngx_buf_t *tmp_buf; if(ch) { subscribers = ch->subscribers; last_seen = ch->last_seen; messages = ch->messages; } switch(status) { case NCHAN_MESSAGE_QUEUED: case NCHAN_MESSAGE_RECEIVED: if(fsub->sub.cf->sub.websocket) { //don't reply with status info, this websocket is used for subscribing too, //so it should only be recieving messages return NGX_OK; } if(r->headers_in.accept) { accept_header = &r->headers_in.accept->value; } tmp_buf = nchan_channel_info_buf(accept_header, messages, subscribers, last_seen, NULL); ngx_memcpy(&fsub->msg_buf, tmp_buf, sizeof(*tmp_buf)); fsub->msg_buf.last_buf=1; nchan_output_filter(fsub->request, websocket_frame_header_chain(fsub, WEBSOCKET_TEXT_LAST_FRAME_BYTE, ngx_buf_size((&fsub->msg_buf)))); break; case NGX_ERROR: case NGX_HTTP_INTERNAL_SERVER_ERROR: assert(0); break; } return NGX_OK; }