luchenqun
12/14/2017 - 2:07 AM

websocket-note.md

关于Websokket的一些备忘录

任务描述

目前发布合约的过程(truffle) eth_sendTransaction(data):data为合约二进制代码,返回发布交易hash
eth_newBlockFilter():监视新块的产生,返回过滤器索引
eth_getFilterChanges(idx):轮询
eth_getFilterChanges(idx):轮询
......
eth_getFilterChanges(idx):轮询,有结果了,返回相关联的hash
eth_getTransactionReceipt(hash):hash为发布合约交易hash,返回交易回执
eth_getCode(addr):addr为合约地址,返回合约二进制代码
eth_uninstallFilter(idx):idx为过滤器索引,卸载过滤器,结束发布过程。

发布过程存在低效的轮询操作,拟通过长连接机制直接向交易发起方发送一系列响应。

写交易的过程(truffle)
eth_sendTransaction(to,data):to表示目标合约地址,data表示目标函数和输入参数,返回交易hash
eth_getTransactionReceipt(hash):hash为写交易hash,轮询
eth_getTransactionReceipt(hash):轮询
......
eth_getTransactionReceipt(hash):轮询,有结果了,返回交易回执,写交易结束。

发起写交易的过程存在低效的轮询操作,需要优化。
建议先从写交易入手,实现长连接通信之后,再优化发布交易的过程。

一些资料

任务分解

  • 服务端即eth程序增加WebSocket通信模块
  • 客户端即Truffle增加webSocket通信模块

服务端WebSocket库

由于服务端程序使用c/c编写,需要集成第三方的C库库。通过搜索一番Google之后,找到如下一些库(star截止于2017/09/26):

库名star 数依赖库文档情况
uWebSockets7833libuv,boost,openssl,zlib无任何文档,但有test
websocketpp1915boost有文档
libwebsockets1316openssl有文档
beast880boost, openssl有文档

Node.js WebSocket库

库名star 数文档情况
ws6240有文档
socket.io-client4863有文档,但是官网挂了
faye3935有文档

简单样例

使用Node.js的ws包搭建的一个使用websocket通讯的简单示例。
服务端

const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 3000 });

wss.on('connection', function connection(ws) {
    ws.on('message', function incoming(message) {
        console.log(`received: ${message}`);
        ws.send(message)
    });
});

客户端端

const WebSocket = require('ws');
const ws = new WebSocket('ws://127.0.0.1:3000');
var index = parseInt(Math.random() * 1000);

ws.on('open', function open() {
    setInterval(() => {
        try {
            var data = new Date().getTime();
            ws.send(`${index}:${data}`);
        } catch (error) {
            console.log(`error:${error}`);
        }
    }, 3000);
});

ws.on('message', function incoming(data) {
    console.log(`receive:${data}`);
});

node ws-server-sample.js启动服务端,输出如下:

received: 779:1506415768082
received: 779:1506415771084
received: 779:1506415774085
received: 521:1506415776042
received: 779:1506415777087
received: 521:1506415779043
received: 779:1506415780088

当然,服务端也可以用uWebSockets库,代码如下:

void serveBenchmark() {
    uWS::Hub h;
    h.onMessage([&h](uWS::WebSocket<uWS::SERVER> *ws, char *message, size_t length, uWS::OpCode opCode) {
        std::cout << "receive msg:" << length << ":";
        for(int i=0; i<length; i++){
            std::cout << message[i];
        }
        std::cout << ", ws = " << ws << std::endl;
        ws->send(message, length, opCode);
    });

    //h.getDefaultGroup<uWS::SERVER>().startAutoPing(1000);
    h.listen(3000);
    h.run();
}

node ws-client-sample.js 启动2个客户端,输出如下:
客户端1:

receive:779:1506415768082
receive:779:1506415771084
receive:779:1506415774085
receive:779:1506415777087
receive:779:1506415780088

客户端2:

receive:521:1506415776042
receive:521:1506415779043