void _bus_terminal_update_channels(bus_terminal_t* bt) { struct bus_terminal_channel_t* btc; int32_t i, ret; assert(bt && bt->bus); // load terminal channel info bt->local_channel_version = bt->bus->channel_version; for (i = 0; i < bt->bus->channel_count; ++ i) { if (bt->bus->channels[i].from == bt->self && idtable_get(bt->send_channels, bt->bus->channels[i].to) == NULL) { btc = bus_terminal_channel_init(bt->bus->channels[i].shmkey, bt->bus->channels[i].from, bt->bus->channels[i].to, bt->bus->channels[i].channel_size, 1); assert(btc); ret = idtable_add(bt->send_channels, bt->bus->channels[i].to, btc); assert(0 == ret); } else if (bt->bus->channels[i].to == bt->self && idtable_get(bt->recv_channels, bt->bus->channels[i].from) == NULL) { btc = bus_terminal_channel_init(bt->bus->channels[i].shmkey, bt->bus->channels[i].from, bt->bus->channels[i].to, bt->bus->channels[i].channel_size, 1); assert(btc); ret = idtable_add(bt->recv_channels, bt->bus->channels[i].from, btc); assert(0 == ret); } } }
uint32_t bus_terminal_send_bytes(bus_terminal_t* bt, bus_addr_t to) { struct bus_terminal_channel_t* btc; if (!bt) return 0; btc = (struct bus_terminal_channel_t*)idtable_get(bt->send_channels, to); if (!btc) return 0; return rbuffer_write_bytes(bus_terminal_channel_rbuffer(btc)); }
uint32_t bus_terminal_recv_bytes(bus_terminal_t* bt, bus_addr_t from) { struct bus_terminal_channel_t* btc; if (!bt) return 0; btc = (struct bus_terminal_channel_t*)idtable_get(bt->recv_channels, from); if (!btc) return 0; return rbuffer_read_bytes(bus_terminal_channel_rbuffer(btc)); }
static void _wscon_close(int fd, void* arg) { WSCtx* ctx = idtable_get(con_table, fd); assert(ctx); printf("fd[%d] close \n", fd); wsconn_release(ctx->con); FREE(ctx); idtable_remove(con_table, fd); }
int32_t bus_terminal_recv(bus_terminal_t* bt, char* buf, size_t* buf_size, bus_addr_t from) { struct bus_terminal_channel_t* btc; int32_t ret; if (!bt) return bus_err_fail; btc = (struct bus_terminal_channel_t*)idtable_get(bt->recv_channels, from); if (!btc) return bus_err_peer_not_found; ret = rbuffer_read(bus_terminal_channel_rbuffer(btc), buf, buf_size); return ret == 0 ? bus_err_empty : bus_ok; }
int32_t bus_terminal_send(bus_terminal_t* bt, const char* buf, size_t buf_size, bus_addr_t to) { struct bus_terminal_channel_t* btc; int32_t ret; if (!bt) return bus_err_fail; btc = (struct bus_terminal_channel_t*)idtable_get(bt->send_channels, to); // if no channel, then dynamic alloc one if (!btc) { ret = _bus_terminal_register_channel(bt, to, BUS_CHANNEL_DEFAULT_SIZE); if (ret != bus_ok) { return ret; } } btc = (struct bus_terminal_channel_t*)idtable_get(bt->send_channels, to); assert(btc); // send buffer ret = rbuffer_write(bus_terminal_channel_rbuffer(btc), buf, buf_size); return ret == 0 ? bus_ok : bus_err_send_fail; }
static int _wscon_read(int fd, void* arg, const char* buffer, int buflen) { WSCtx* ctx = idtable_get(con_table, fd); if(!ctx) return -1; printf("fd[%d] read %d bytes\n", fd, buflen); if (wsconn_send(ctx->con, buffer, buflen) < 0) { printf("send back fail\n"); return -1; } int i = 0; while (i < buflen) { printf("%c", buffer[i++]); } printf("\n"); return buflen; }
int test_ws_server() { con_table = idtable_create(1024); assert(con_table); r = reactor_create(); assert(r); acc_t* acc = acc_create(r); assert(acc); acc_set_read_func(acc, _accept_read, NULL); struct sockaddr_in addr; int res = sock_addr_aton(WS_IP, WS_PORT, &addr); assert(res == 0); res = acc_start(acc, (struct sockaddr*)&addr); assert(res == 0); while (1) { res = reactor_dispatch(r, 1); if(res < 0) return -1; if(res == 0) usleep(100); } acc_stop(acc); acc_release(acc); for (int i = 0; i < 1024; i++) { WSCtx* ctx = idtable_get(con_table, i); if (ctx) { wsconn_release(ctx->con); FREE(ctx); } } idtable_release(con_table); reactor_release(r); return 0; }