void pbntf_update_socket(pubnub_t *pb, pb_socket_t socket) { PUBNUB_UNUSED(socket); EnterCriticalSection(&m_watcher.mutw); update_socket(&m_watcher, pb); LeaveCriticalSection(&m_watcher.mutw); }
//等待UDT连接的数据 //如果有网络消息到了则返回消息的长度(整条消息的长度,到来的数据长度) //超时,出错返回-1,检测返回值.返回0没有数据超时 static NEINT32 _wait_udt(ne_udt_node *socket_addr, ne_packetbuf_t *out_buf, netime_t tmout) { NEINT32 ret ,data_len; udt_pocketbuf msg_buf ; if(-1==update_socket(socket_addr) ) return -1 ; ret = _wait_data(socket_addr, &msg_buf,tmout) ; if(ret <=0) return ret ; if(PROTOCOL_UDP==POCKET_PROTOCOL(&(msg_buf.pocket))){ struct neudp_packet *packet = (struct neudp_packet *)&msg_buf ; //ne_packhdr_t *tmp = (ne_packhdr_t*)(packet->data) ; data_len = ret - sizeof(struct neudp_packet) ; //if(packet->session_id!=socket_addr->session_id) // return 0; if(data_len==ne_pack_len(((ne_packhdr_t*)(packet->data)))) { memcpy(out_buf,packet->data, data_len) ; return data_len ; } return 0 ; } if(socket_addr->is_datagram) { socket_addr->datagram_entry = NULL ; if(-1==udt_parse_rawpacket(socket_addr, &msg_buf, ret) ) return -1 ; data_len = ret - sizeof(struct neudt_pocket) ; if(data_len==ne_pack_len(((ne_packhdr_t*)(msg_buf._buffer)))) { memcpy(out_buf,msg_buf._buffer, data_len) ; return data_len ; } return 0 ; } else { if(-1==udt_parse_rawpacket(socket_addr, &msg_buf, ret)) return -1 ; ret = _fetch_udt_msg(socket_addr,&out_buf->hdr) ; } return ret ; }
/* 更新客户端的网络连接 */ NEINT32 ne_connector_update(ne_netui_handle net_handle,netime_t timeout) { NEINT32 ret =0; ne_assert(net_handle ) ; if(net_handle->nodetype==NE_TCP){ NEINT32 read_len ; //把tcp的流式协议变成消息模式 struct ne_tcp_node *socket_node = (struct ne_tcp_node *) net_handle ; socket_node->myerrno = NEERR_SUCCESS ; //首先清空发送缓冲 if(0==ne_tcpnode_trytolock(socket_node)) { ne_tcpnode_flush_sendbuf(socket_node) ; ne_tcpnode_unlock(socket_node) ; } if(timeout) { ret = ne_socket_wait_read(socket_node->fd,timeout) ; if(ret<=0) return ret ; } RE_READ: read_len = ne_tcpnode_read(socket_node) ; if(read_len<=0) { if(socket_node->myerrno==NEERR_WUOLD_BLOCK) { return 0 ; } return read_len ; } else { ret += read_len ; if(-1==tcpnode_parse_recv_msgex(socket_node,stream_data_entry, NULL) ){ //ne_tcpnode_close(socket_node,1) ; return -1 ; } if(TCPNODE_READ_AGAIN(socket_node)) { /*read buf is to small , after parse data , read again*/ goto RE_READ; } } } else if(net_handle->nodetype==NE_UDT) { ne_udt_node *socket_addr =(ne_udt_node *) net_handle ; udt_pocketbuf msg_buf ; socket_addr->myerrno = NEERR_SUCCESS ; if(-1==update_socket(socket_addr) ) return -1 ; ret = _wait_data(socket_addr, &msg_buf,timeout) ; if(ret <=0) return ret; if(PROTOCOL_UDP==POCKET_PROTOCOL(&(msg_buf.pocket))){ /*处理udp消息,提前过来消息*/ struct neudp_packet *packet = (struct neudp_packet *)&msg_buf ; NEINT32 data_len = ret - sizeof(struct neudp_packet) ; //if(packet->session_id!=socket_addr->session_id) // return 0; return _datagram_entry(socket_addr, packet, data_len,NULL) ; } if(socket_addr->is_datagram) { //直接使用UDP的消息模式 //这里需要处理返回-1关闭连接 socket_addr->datagram_entry = _datagram_entry ; socket_addr->callback_param = NULL ; ret = udt_parse_rawpacket(socket_addr, &msg_buf, ret) ; } else { //把udt的stream模式变成消息模式 //这里需要处理返回-1关闭连接 if(-1==udt_parse_rawpacket(socket_addr, &msg_buf, ret)) return -1 ; ret = parse_udt_stream(socket_addr, stream_data_entry, NULL) ; } // update if(-1==update_socket(socket_addr) ) return -1 ; } return ret; }
int main(int argc, char *argv[]) { ssl_init(); OrderBook order_book(3); Orders<1000> orders; auto poller = Poller::create(); Url diff_url("wss://ws.pusherapp.com/app/de504dc5763aeef9ff52?protocol=5"); auto diff_socket = create_tcp_socket(diff_url.host(), 80); diff_socket->set_callbacks<DiffLogic<1000>>(std::ref(diff_url), std::ref(orders)); poller->update_socket(diff_socket, EPOLLIN | EPOLLOUT); Url order_book_url("https://www.bitstamp.net/api/order_book"); auto order_book_socket = create_tcp_socket(order_book_url.host(), 443); order_book_socket->set_callbacks<ReceiveOrderBookLogic>(std::ref(order_book_url), std::ref(order_book)); poller->update_socket(order_book_socket, EPOLLOUT | EPOLLIN); //---------------------- std::shared_ptr<Order> order; Timer reconect_timer; Timer update_timer; Timer stop_timer; stop_timer.reset(); uint64_t last_time = 0; const uint64_t RECONECT_INTERVAL = 20; bool order_book_ready = false; for (;;) { poller->poll(); for (;;) { auto event = poller->get_next_event(); if (!event.action) break; try { if (event.action & PollerEvent::READ) event.socket->read(); if (event.action & PollerEvent::WRITE) event.socket->write(); if (event.action & PollerEvent::CLOSE) event.socket->close(event.close_reason); } catch (const std::exception & e) { std::cerr << "Exception in callback: " << e.what() << std::endl << "Closing socket." << std::endl; event.socket->close(); } } if (!order_book) { if (!order_book_socket.get() && reconect_timer.elapsed_seconds() > RECONECT_INTERVAL) { std::cerr << "creating new order_book_socket" << std::endl; order_book_socket = create_tcp_socket(order_book_url.host(), 443); order_book_socket->set_callbacks<ReceiveOrderBookLogic>(std::ref(order_book_url), std::ref(order_book)); poller->update_socket(order_book_socket, EPOLLOUT | EPOLLIN); } continue; } if (!order_book_ready) { uint64_t first_diff_timestamp = orders.get_first_timestamp(); uint64_t last_book_timestamp = order_book.get_last_timestamp(); std::cerr << first_diff_timestamp << "/" << last_book_timestamp << std::endl; if (last_book_timestamp < first_diff_timestamp) { order_book.clear(); reconect_timer.reset(); order_book_socket.reset(); continue; } order_book_ready = true; } while (order = orders.get_order()) order_book.add(*order); if (update_timer.elapsed_seconds() != last_time) { last_time = update_timer.elapsed_seconds(); order_book.print(); } } ssl_destroy(); return 0; }