nodejs 开发websocket 笔记

2018-09-29  本文已影响0人  马贞晓

使用nodejs 开发websocket消息分发系统

websocket使用事件触发机制传输密集传输数据,跟nodejs的事件机制相同,比起早期comet技术使用的http响应式更为高效,客户端不用重复的与服务端握手更加节约服务器性能。

1、在客户端调用

socket事件

message 消息接收
open 与服务器握手完成后触发相对与服务端的upgrade事件
close socket关闭
error 错误消息
ws.send 发送消息,消息内容必须为字符串或buffer

let url = "ws://127.0.0.1:3000/socket?id="+id+"&name="+name+"&gid="+teamid;

let ws= new WebSocket(url);

ws.addEventListener("message",this.message.bind(this));
ws.addEventListener("open",this.open.bind(this));
ws.addEventListener("close",this.close.bind(this));
ws.addEventListener("error",this.error.bind(this));

ws.send("消息发送");
2、服务端接收调用

在服务端使用koa-websocket

其响应原理为客户端请求后,服务端切换响应为websocket,在upgrade事件中

1、收到客户端请求头

upgrade:websocket
connection:upgrade
Sec-WebSocket-Key:xxxx==

2、服务端使用258EAFA5-E914-47DA-95CA-C5AB0DC85B11通过sha1散列算法合并key手动修改Sec-WebSocket-Key 返回客户端完成
3、upgrade事件参数req,socket,upgradehead,

socket.setNoDelay(true)
socket.write(修改过端返回头)
websocket = new WebSocfket()
websocket.setSocket(socket) 创建websocket链接

message响应客户端事件 ws.send() 发送客户端事件

let ws = ctx.websocket;
    ws.on("message",this.EVNET_MESSAGE.bind(this));
    ws.on("error",this.EVENT_ERROR.bind(this));
    ws.on("close",this.EVENT_CLOSE.bind(this));
    ws.on("timeout",this.EVENT_ERROR.bind(this));  
 

3、在后期开发中加入了redis与mssql 来进行数据存储操作

因为redis自己有重连机制,不需要在处理重新连接,与sql数据库操作不同,不用重复端去调用初始化,此处为坑

 this.client = redis.createClient({
            host:host,port:port,
            retry_strategy(options){
                if (options.error.code === 'ECONNREFUSED') {
                    
                    console.log('连接被拒绝');
                    Log.error('连接被拒绝');
                }
                if (options.times_connected > 10) {
                    console.log('重试连接超过十次');
                    Log.error('重试连接超过十次');  
                    
                }
                return Math.max(options.attempt * 100, 3000);
            }
        });

4、mssql

使用 new sql.ConnectionPool(this.config).connect();创建链接
在查询完成后sql.close();来关闭链接,跟api上说明使用pool.close()不同,pool会造成二次连接数据库失败。此处为坑


const sql = require('mssql');
class xx{

connect(){  //创建链接
        return new sql.ConnectionPool(this.config).connect();
        
    }
    
    async query(str){  //查询数据
        console.log("查询或入库")
        let pool;
        let result;
     try{
        pool = await  this.connect()
        result = await pool.request().query(str)
        }catch(e){
            console.log("数据库链接错误:"+e.message);
            Log.error("数据库链接错误:"+e.message);
            return Promise.reject(e.message).catch(str=>{
                this.emit("DBError",str);
            })
        }
      
       
      let rows = result.recordset; 
      let data=[]
         if(result.recordsets.length){
            data = result.recordsets[0];
            }     
           sql.close();
         return Promise.resolve(toJson(data))    
    }
}
上一篇下一篇

猜你喜欢

热点阅读