NodeJs使用nodejs-websocket + protobuf
参考:
HTML5+NodeJs实现WebSocket即时通讯 (某人的blog)
nodejs-websocket使用示例 (www.npmjs.com网站,有示例)
Buffer API (nodejs api 中文版)
nodejs-websocket + protobufjs

一 安装nodejs-websocket
在服务端项目文件夹下,新建一个pageage.json
{
"name": "realtime-server",
"version": "0.0.1",
"description": "my first realtime server",
"dependencies": {
"nodejs-websocket": "^1.7.2",
"protobufjs": "^6.8.8"
}
}
在服务端项目文件夹下shift+右键,在此处打开命令窗口,输入
npm install nodejs-websocket
安装完毕后,项目目录下会增加node_modules文件夹

二 安装protobufjs
在服务端项目文件夹下shift+右键,在此处打开命令窗口,输入
npm install protobufjs
输入后回车,等待安装完毕,如下图:

三 准备测试用.proto文件
准备一个测试用的proto文件,如下
login.proto
//登录
package login; //登录请求
message LoginReq{
required int32 uid = 1; //用户id
}
proto文件转成.js
将login.proto放在服务端项目文件夹下

shift+右键,打开命令窗口,生成js
pbjs -t static-module -w commonjs -o login.js login.proto
生成d.ts (服务端不需要,客户端需要)
pbts -o login.d.ts login.js

四 服务端代码
服务端连接成功后,等待接收。 如果接收到登录请求,则解析loginReq,然后返回一个loginReq。
直接使用login.proto文件示例:
var ws = require("nodejs-websocket");
var protobufjs = require("protobufjs");
var root = protobufjs.loadSync("./login.proto"); //直接使用login.proto文件
console.log("开始创建websocket");
var server = ws.createServer(function(conn){
console.log("连接成功");
conn.on("binary", function (inStream) {
console.log("接收消息");
var data;
inStream.on("readable", function () {
data = inStream.read();
})
inStream.on("end", function () {
console.log("Received " + data.length + " bytes of binary data");
//解析接收的数据,cmd
var cmd = data.readUInt16BE(0);
console.log("接收数据的cmd:",cmd);
let bytes = Buffer.from(data,1);
//解析接收的数据,loginReq
var LoginReq = root.lookupType("login.LoginReq");
var loginReq = LoginReq.decode(bytes);
console.log("接收数据的uid:", loginReq.uid);
//发送的数据,loginReq
var sendLoginReq = LoginReq.create();
sendLoginReq.uid = 123;
var sendData = LoginReq.encode(sendLoginReq).finish();
//发送的数据,cmd
var sendBuffer = Buffer.alloc(2);
sendBuffer.writeInt16BE(100);
//拼接数据并发送
var totalBuffer = Buffer.concat([sendBuffer,sendData],sendData.length + sendBuffer.length);
conn.sendBinary(totalBuffer);
})
})
conn.on("close", function (code, reason) {
console.log("关闭连接")
});
conn.on("error", function (code, reason) {
console.log("异常关闭")
});
}).listen(8001)
console.log("开始创建websocket完毕");
使用转换后login.js文件示例:
var root = require("./login"); //使用login.js文件
//连接成功
io.on('connection', function(socket){
console.log('a user connected');
//监听登录请求
socket.on('login', function(data,callback){
//解析登录数据
var loginReqObj = root.login.LoginReq.decode(data);
console.log("请求登录的用户:",loginReqObj.uid);
//返回登录响应
let loginResObj = root.login.LoginRes.create();
loginResObj.code = 200;
var buffer = root.login.LoginReq.encode(loginResObj).finish();
socket.emit('login', buffer);
});
});
五 客户端代码
客户端请求连接服务端,连接成功后发送登录请求loginReq
/**连接成功*/
private onConnect(e:egret.Event){
console.log("ClientSocket 连接成功");
this.resetReconnect();
App.EventMananger.sendEvent(ClientSocket.SOCKET_CONNECT); //测试
let loginData:login.LoginReq = new login.LoginReq();
loginData.uid = 123;
let buffer = login.LoginReq.encode(loginData).finish();
this.send(100, buffer);
} /**
* 发送数据
* @param cmd 数据协议
* @param sendByte 发送的数据
*/
public send(cmd:number, sendByte:Uint8Array){
console.log("ClientSocket 发送:",cmd);
//发送的数据cmd+proto
let sendByteArray = new egret.ByteArray(sendByte);
let byteArray:egret.ByteArray = new egret.ByteArray();
byteArray.writeUnsignedShort(cmd);
byteArray.writeBytes(sendByteArray);
//发送
this.socket.writeBytes(byteArray);
this.socket.flush();
} /**接收数据*/
private onReceive(e:egret.Event){
//读取socket数据
var byte:egret.ByteArray = new egret.ByteArray();
this.socket.readBytes(byte);
//读取cmd+proto
let cmd:number = byte.readUnsignedShort();
console.log("接收数据,cmd:",cmd);
//读取loginReq
let revByteArray:egret.ByteArray = new egret.ByteArray();
byte.readBytes(revByteArray);
let buffer:login.LoginReq = login.LoginReq.decode(revByteArray.bytes);
console.log("接收数据,uid:",buffer.uid);
}
六 测试结果
运行服务端和客户端
1. 客户端请求连接服务端
2. 连接成功后,客户端发送登录请求loginReq
3. 服务端接收到登录请求,解析loginReq并打印。 然后再返回一个loginReq。
4. 客户端接收到服务端返回的loginReq,解析并打印。
服务端输出:

客户端输出:

到此,一个简单的nodejs-websocket + protobufjs服务单搭建和联调测试完成。
问题:
一 nodejs服务端关于Buffer的操作
看了一下Buffer的Api,没有找到writeBytes的方法,只有concat来拼接数据。
NodeJs使用nodejs-websocket + protobuf的更多相关文章
- nodejs——js 实现webSocket 兼容移动端
nodejs——js 实现webSocket 兼容移动端 //服务器端 //npm install --save ws const express = require('express'); cons ...
- NodeJS反向代理websocket
如需转载请标明出处:http://blog.csdn.net/itas109QQ技术交流群:129518033 文章目录NodeJS反向代理websocket@[toc]前言代码相关问题:1.http ...
- NodeJs 实现简单WebSocket 即时通讯
至于服务器语言选择nodeJs,一是因为自己是做前端的,对javascript比较熟悉,相比于其他后台语言,自然会更喜欢nodeJs了, 二是NodeJs本身事件驱动的方式很擅长与大量客户端保持高并发 ...
- 用nodejs快速实现websocket服务端(带SSL证书生成)
有不少公司将nodejs的socket.io作为websocket的解决方案,很遗憾的是socket.io是对websocket的封装,并不支持html5原始的websocket协议,微信小程序使用的 ...
- NodeJS client code websocket
var WebSocketClient = require('websocket').client; var client = new WebSocketClient(); client.on('co ...
- 使用node-inspector调试nodejs程序<nodejs>
1.npm install -g node-inspector // -g 导入安装路径到环境变量 一般是c盘下AppData目录下 2.node-inspector & //启动node- ...
- 【nodejs】nodejs 的linux安装(转)
(一) 编译好的文件 简单说就是解压后,在bin文件夹中已经存在node以及npm,如果你进入到对应文件的中执行命令行一点问题都没有,不过不是全局的,所以将这个设置为全局就好了. ./node -v ...
- nodejs01--什么是nodejs,nodejs的基本使用
nodejs使用范围 -直接在cmd命令行运行,在你的电脑上直接运行 -可以搭建一个web服务器(express,koa) -一些基本的使用 -modules是如何工作的 -npm管理modules ...
- 【Nodejs】Nodejsの環境構築
参考URL:http://www.runoob.com/nodejs/nodejs-install-setup.html Windowにインストールする方法を紹介します. ▲ダウンロードURL:htt ...
- [NodeJs] 用Nodejs+Express搭建web,nodejs路由和Ajax传数据并返回状态,nodejs+mysql通过ajax获取数据并写入数据库
小编自学Nodejs,看了好多文章发现都不全,而且好多都是一模一样的 当然了,这只是基础的demo,经供参考,但是相信也会有收获 今天的内容是用Nodejs+Express搭建基本的web,然后呢no ...
随机推荐
- C# Task的GetAwaiter和ConfigureAwait
个人感觉Task 的GetAwaiter和ConfigureAwait也是比较好理解的,首先看看他们的实现 public class Task<TResult> : Task { //Ge ...
- Hadoop Ls命令添加显示条数限制參数
前言 在hadoop的FsShell命令中,预计非常多人比較经常使用的就是hadoop fs -ls,-lsr,-cat等等这种与Linux系统中差点儿一致的文件系统相关的命令.可是细致想想,这里还是 ...
- jvm理论-字节码指令
Java虚拟机的指令由一个字节长度的.代表着某种特定操作含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需参数(称为操作数,Operands)而构成. 基本数据类型 1.除了l ...
- mysql数据库全备和全备还原(使用Xtrabackup)
一.使用innobackupex创建全备 语法 innobackupex --user=DBUSER --password=DBUSERPASS /path/to/backup/dir/ innoba ...
- CentOS7 限制SSH密码尝试次数
编辑配置文件: vi /etc/pam.d/sshd 在文末添加内容: auth required pam_tally2.so deny= unlock_time= 代表失败5次,禁止访问600秒 保 ...
- Community宣言
Community宣言 一个幽灵,共产主义的幽灵,在欧洲游荡.为了对这个幽灵进行神圣的围剿,旧欧洲的一切势力,教皇和沙皇.梅特涅和基佐.法国的激进派和德国的警察,都联合起来了. 有哪一个反对党不被它的 ...
- Linux下清理内存和Cache方法见下文:
暂时目前的环境处理方法比较简单: 在root用户下添加计划任务: */10 * * * * sync;echo 3 > /proc/sys/vm/drop_caches; 每十分钟执行一次,先将 ...
- mysql distinct 用法详解及优化
本事例实验用表task,结构如下 MySQL> desc task; +-------------+------------+------+-----+-------------------+- ...
- IntelliJIdea 2016.2 使用 tomcat 8.5 调试spring的web项目时,bean被实例化两次导致timer和thread被启动了两遍的问题的解决
今天新搭建了一个spring的web项目,项目启动时会启动一个线程,线程里定时执行任务,另外还启动了一个定时器,每秒钟统计系统吞吐量等业务性能数据.但是调试的时候惊奇的发现定时器和线程均被启动了两次. ...
- 关于Java 软件工程师应该知道或掌握的技术栈
鄙人星云,今天突然想写这么一篇需要持续更新的文章,主要目的用于总结当前最流行的技术和工具,方便自己也方便他人. 更新时间:2018-10-23 09:26:19 码农职业路径图 码农入门职业路径图 J ...