Layaair Socket.io 的使用

霸气de小男生 提交于 2019-11-29 05:44:45

                                                  Layaair Socket.io 的使用

  • 客户端 使用Layaair 1.7.x 版本   socket.io.d.ts 是从 Egret 搬过来的, socket.io.js 库 是客户端 和 服务器公用的
  • 服务器 nodejs 
  • 协议  protobuf

Socket.io 对比 Websocket 的优势太多了,但是Layaair 没有提供 对 Socket.io 的支持,所以呢 参照了 Egret ,应为用的传输 协议是protobuf , 

客户端和服务器 对 protobuf 的 .proto  的解析都是采用 静态解析,

对于Layaair 的 静态解析前面的博客有提到 不熟悉的同学可以参照下

https://blog.csdn.net/nicepainkiller/article/details/83115669

对于 nodejs  静态集成  protobuf 的 .proto 这里和大家 分享下

这个我的 nodejs 工作目录,两个 .proto 文件 在 protofile  文件夹中 生成的 net_msg.js 是在 protojs 文件夹中

在这里我么把服务器的整个 流程走一个

1  安装 socket.io

npm install socket.io --save

2 安装  protobufjs

npm install protobufjs --save

3 安装  .proto 编译工具 用于把 .proto 编译成 .js 使用

npm install pbjs

或者
npm install protobufjs -g --save

 

对照我的项目路径    我的编译命令 就这么写了

  • ./protofile/net_msg.proto  是要编译文件相对路径
  • ./protoJs/net_msg.js         是生成文件的相对路径
  • 其他的照着写就好
pbjs -t static-module ./protofile/net_msg.proto -w commonjs > ./protoJs/net_msg.js

你也可以写个 .bat 工具  一键生成 对应的 js

@echo off
echo pbjs 静态编译  开始
pbjs -t static-module ./protofile/net_msg.proto -w commonjs > ./protoJs/net_msg.js
echo pbjs 静态编译  结束

pause

使用由 .proto生成 的js 

const netProto = require('./protobuf/protoJs/net_msg')['netProto']

'./protobuf/protoJs/net_msg' 是 .js 路径 后面中括号 是 .proto 的 'package' 名称 就是包名;

 Hearbeat 是  .proto 里面定义的一个‘类’

        let heartbeat = new netProto.Heartbeat()
        heartbeat.msgType   = 9
        heartbeat.timeStamp = 666666

        console.log("001:", netProto.Heartbeat.encode(heartbeat).finish())//解码


        let obj = netProto.Heartbeat.decode( data)//编码
        console.log(obj)

        console.log(obj.msgType)
        console.log(obj.timeStamp)

        socket.broadcast.send(netProto.Heartbeat.encode(heartbeat).finish())

 服务端完整代码:

 

//引用 Http 模块
const http = require('http')
//文件读写
const fs = require('fs');
//床架一个WEB服务 socket 基于 Web 服务
const app = http.createServer()
//引用 socket.io 模块 
const io = require('socket.io')(app)
const port = 3000
 
const netProto = require('./protobuf/protoJs/net_msg')['netProto']


app.listen(port, function () {
    console.log('服务器启动成功!端口监听:' + port)
});


let onLineConnets = {}
let index = 0

io.on('connect', onConnect);
function onConnect(socket) {
    console.log('有机器连接服务器')
    
    socket.name = ++index;
    onLineConnets[socket.name] = socket


    socket.on('message', function (data) {
        console.log("data:", data)
        //let obj =  messages.heartbeat.decode(data)
        // console.log(obj)
        // console.log(obj.msg_type)
        // console.log(obj.timeStamp)


        let heartbeat = new netProto.Heartbeat()
        heartbeat.msgType   = 9
        heartbeat.timeStamp = 666666

        //console.log("000:", netProto.Heartbeat.encode(heartbeat))
        console.log("001:", netProto.Heartbeat.encode(heartbeat).finish())


        let obj = netProto.Heartbeat.decode( data)
        console.log(obj)

        console.log(obj.msgType)
        console.log(obj.timeStamp)

        socket.broadcast.send(netProto.Heartbeat.encode(heartbeat).finish())
         

    })

    socket.on('disconnect', function () {
        console.log('客户端断开连接')
        delete onLineConnets[socket.name]
    })
    socket.on('error', function () {
        console.log('客户端发生错误')
        delete onLineConnets[socket.name]
    })


    
}
 

 

 

Layaair 客户端中 解析 和 发送需要和 服务器对于上 要不然出问题,

这里面有需要两个文件 一个是 socket.io.d.ts 另一个是   socket.io.js

需要的 index.html 中 引入socket.io.js

  socket.io.d.ts 放入Libs中

下载地址

 

 

/*
* socket 消息先关; BaseSingleton 单例
*/
class SocketManager extends BaseSingleton {

    private socket: SocketIOClient.Socket;//socket.io.d.ts中定义
    private serverHost: string;
    public socketProxy: MessageBase;//处理协议的中间件
    constructor() {
        super()
    }

    public connect(url): void {
        if (this.isConnect) {
            this.closeConnect();
        }

        this.serverHost = url

        Log.trace("开始连接服务器服务器: " + url);
        let self = this;
        this.socket = io.connect(url)
        this.socketProxy =  new MessageProxy(this.socket)
        this.socket.on(SocketConst.SOCKET_CONNECT, function () {
            self.onSocketConnect()
        });

        this.socket.on(SocketConst.SOCKET_DISCONNECT, function () {
            self.onSocketDisconnect()
        })

        this.socket.on(SocketConst.SOCKET_ERROR, function () {
            self.onConnectError()
        })

        this.socket.on(SocketConst.SOCKET_MESSAGE, function (message: any) {
            self.onSocketMessage(message)
        })

    }

    public get isConnect(): boolean {
        if (this.socket != null && this.socket.connected == true) {
            return true;
        }
        else {
            return false;
        }
    }

    public get SocketProxy():MessageBase{
        return this.socketProxy
    }

    public closeConnect(): void {
        if ( this.isConnect) {
            this.socket.close()
        }
    }

    private onSocketConnect(): void {
        Application.MessageCenter.dispatch(MessageConst.SOCKET_CONNCETSCUESS);
    }

 
    private onSocketDisconnect(): void {
        Log.trace("断开连接!");
        Application.MessageCenter.dispatch(MessageConst.SOCKET_DISCONNECT);
    }

    private onConnectError(e: Event = null): void {
        Log.trace("连接错误!", e);
        Application.MessageCenter.dispatch(MessageConst.SOCKET_CONNCETERROR);
    }

    private onSocketMessage(message: any) {
        this.socketProxy.receive(message);
        
    }
}

 

这个脚本主要集成了 发送 编码 socket 和 收到socket 解析

/*
* name;
*/
class MessageProxy implements MessageBase {
    private socket: SocketIOClient.Socket;


    private bufferReceive: Laya.Byte;
    private bufferSend: Laya.Byte;
    private receiveArray: Uint8Array;

    constructor(socket: SocketIOClient.Socket) {
        this.socket = socket
        this.bufferReceive = new Laya.Byte();
        this.bufferSend = new Laya.Byte();

    }

    public receive(msg: any): void {
        //console.log('receive===>', msg)
        let base: netProto.IBaseMsg = this.decode(msg)
        //把消息广播出去
        Application.MessageCenter.dispatch(base.msg_type.toString(), this.receiveArray);
    }

    public send(msg: any, encode: Function): void {
        this.socket.send(this.encode(msg, encode).buffer)
    }

    public decode(msg: any): any {
        this.bufferReceive.clear()
        this.bufferReceive.writeArrayBuffer(msg)
        console.log("BaseMsg:", this.bufferReceive.buffer)
        this.receiveArray = new Uint8Array(this.bufferReceive.buffer)
        let base: netProto.IBaseMsg = netProto.BaseMsg.decode(this.receiveArray)
        console.log("BaseMsg:", this.bufferReceive.buffer)
        return base;
    }

    public encode(msg: any, encode: Function): any {
        this.bufferSend.clear()
        this.bufferSend.writeArrayBuffer(encode(msg).finish());
        return this.bufferSend;
    }
}

大概的使用:

/*
* name;
*/
class SceneMain extends ui.SceneMainUI {


    constructor() {
        super();
        this.init()

    }

    private init(): void {
        //开始连接 socket
        SocketManager.getInstance().connect(ConfigSocket.getWsRoot)

        //监听sockrt.io 连接成功
        Application.MessageCenter.addListener(MessageConst.SOCKET_CONNCETSCUESS, function () {
            Log.trace('服务器连接成功')




        }, this)

        //  Application.MessageCenter.addListener(SocketConst.SOCKET_NOCONNECT, function(){
        //     Log.trace('服务器连接错误-----')
        // },this)


        //服务器消息 
        Application.MessageCenter.addListener('9', function (date) {

            console.log(date)
            let heartbeat1 = netProto.Heartbeat.decode(date)
            console.log('heartbeat.timeStamp:', heartbeat1.timeStamp)


            let heartbeat = new netProto.Heartbeat()
            heartbeat.msg_type = 9
            heartbeat.timeStamp = new Date().getTime()

            SocketManager.getInstance().SocketProxy.send(heartbeat, netProto.Heartbeat.encode);


        }, this)


        let heartbeat = new netProto.Heartbeat()
        heartbeat.msg_type = 9
        heartbeat.timeStamp = new Date().getTime()

        SocketManager.getInstance().SocketProxy.send(heartbeat, netProto.Heartbeat.encode);
    }

    private login() {


    }



    private randomNum(min, max) {
        return parseInt(Math.random() * (max - min + 1) + min, 10);
    }

}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!