LayaAir引擎的laya.net.Socket
类库是对HTML5中WebSocket接口的封装,允许服务器与客户端进行全双工(full-duplex)的实时通讯,并允许跨域通信。当WebSocket连接建立后,服务器和客户端都能主动向对方发送或接收字符串和二进制数据。使用WebSocket收发数据的格式为二进制或字符串,如果收发二进制数据则需配合laya.utils.Byte
类库使用。
项目 | 名称 | 值 |
---|---|---|
Package |
包 | laya.net |
Class |
类 | public class Socket |
Inheritance |
继承 | Socket / EventDispatcher / Object |
若要使用Socket类的方法,需要首先使用构造函数new Socket
创建一个Socket对象。Socket以异步方式传输和接收数据。WebSocket的连接是异步的,所有后端的数据交互都需要等待open
事件成功,前后端建立连接通道后才能正常收发消息。因此实例化Socket后必须监听四个事件open
、close
、error
、message
。
入门
- 安装WebSocketd服务器,使用Python开发服务器脚本。
WebSocketd服务器软件的下载地址为 http://websocketd.com/,下载安装配置参见官网。
$ vim test.py
import time
print("hello")
- 运行WebSocketd服务器中的脚本
$ websocketd --port=9000 python test.py
- 使用Laya编写WebSocket客户端应用程序
$ vim /src/Test.laya
class Test{
constructor(){
//初始化舞台
this.initStage();
//初始化WebSocket
this.initSocket("127.0.0.1", 9000);
}
initStage(){
//初始化引擎
const canvas = Laya.init(Laya.Browser.clientWidth, Laya.Browser.clientHeight, Laya.WebGL);
//舞台设置
Laya.stage.alignH = Laya.Stage.ALIGN_CENTER;//设置舞台水平居中
Laya.stage.alignV = Laya.Stage.ALIGN_MIDDLE;//设置舞台垂直居中
Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL;//设置舞台缩放模式为显示所有
Laya.stage.bgColor = "#000000";//设置舞台背景颜色为黑色
}
initSocket(host, port){
this.socket = new Laya.Socket();
this.connect(host, port);
this.socket.on(Laya.Event.OPEN, this, this.onOpen);
this.socket.on(Laya.Event.CLOSE, this, this.onClose);
this.socket.on(Laya.Event.ERROR, this, this.onError);
this.socket.on(Laya.Event.MESSAGE, this, this.onMessage);
}
connect(host, port){
const url = `ws:\\${host}:${port}`;
this.socket.connectByUrl(url);
}
onOpen(event){
console.log("socket open");
this.socket.send("hello open");
}
onClose(event){
console.log("socket close");
}
onError(event){
console.log("socket error");
}
onMessage(msg){
console.log(msg);
}
}
new Test();
- 在LayaAir中使用F8快捷键编译并在
bin
目录下生成代码 - 使用Node.js的
http-server
作为HTTP服务器,运行Laya程序。
$ http-server -p 8001 /bin
- 在浏览器中访问LayaAir项目并查看控制台输出内容
http://127.0.0.1:8001/index.html
属性
属性 | 读写 | 作用 |
---|---|---|
conneccted:Boolean |
[readonly] |
表示当前Socket对象是否已经连接 |
disableInput:Boolean = false |
表示是否禁止缓存服务器发送过来的数据 | |
endian:String |
主机字节序 | |
input:* |
[read-only] |
表示缓存的服务器发送过来的数据 |
output:* |
[read-only] |
表示需要发送到服务器缓冲区的数据 |
protocols:* |
子协议名称 |
主机字节序,是CPU存放数据的两种不同顺序,包括大端字节序和小端字节序。
类型 | 名称 | 含义 |
---|---|---|
LITTLE_ENDIAN |
小端字节序 | 地址低位存储值得低位,地址高位存储值得高位。 |
BIG_ENDIAN |
大端字节序 | 地址低位存储值得高位,地址高位存储值的地位。 |
子协议,由多个子协议名称构成的数组。 必须在调用connect
或connectByUrl
之间进行赋值,否则无效。指定后只有当服务器选择了其中的某个子协议,连接才能建立成功,否则连接建立失败并派发Event.ERROR
事件。
方法
方法 | 作用 |
---|---|
Socket(host:String=null, port:int=0, byteClass=null) |
创建Socket对象 |
clearSocket():void |
清理Socket对象 |
close():void |
关闭Socket连接 |
connect(host:String, port:int) |
连接到指定的主机和端口 |
connectByUrl(url:string):void |
连接到指定的WebSocket协议的URL |
flush():void |
发送缓冲区中的数据到服务器 |
send(data:*):void |
发送数据到服务器 |
Socket(host:String=null, port:int=0, byteClass=null)
创建新的Socket对象,默认字节序为Socket.BIG_ENDIAN
。若未指定参数则创建一个最初处于断开状态的套接字。若指定有效参数则尝试连接到指定主机的端口。建议使用不带参数的构造函数,并添加任意事件监听器并设置protocols
等属性,然后再使用host
和port
参数调用connect
方法,确保所有事件监听器和其他流程工作正常。
cleanSocket():void
清理Socket套接字
close():void
关闭Socket连接
connect(host:String, port:int):void
连接到指定主机的端口
- 连接成功则会派发
Event.OPEN
事件 - 连接失败则派发
Event.ERROR
事件 - 连接被关闭则派发
Event.CLOSE
事件 - 接收到数据则派发
Event.MESSAGE
事件
以上除了Event.MESSAGE
事件的参数为数据内容外,其他事件参数都是原生HTML DOM Event
对象。
connectByUrl(url:String):void
连接到指定WebSocket URL的服务器,连接地址URL格式为ws://domain:port
。
flush():void
发送缓冲区中的数据到服务器
send(data:*):void
发送数据到服务器
事件
事件 | 全称 | 描述 |
---|---|---|
close |
Laya.Event.CLOSE |
Socket连接被关闭时触发 |
error |
Laya.Event.ERROR |
Socket连接出现异常时触发 |
open |
Laya.Event.OPEN |
Socket连接建立成功后触发 |
message |
Laya.Event.MESSAGE |
Socket连接接收到服务器发送过来的数据时触发 |
封装
export default class WebSocket{
static getInstance(...args){
if(!this._instance){
this._instance = new WebSocket(...args);
}
return this._instance;
}
constructor(...args){
//发送二进制格式的数据
this.byte = new Laya.Byte();
this.byte.endian = Laya.Byte.LITTLE_ENDIAN;//小端
this.ws = Laya.Socket();
this.ws.endian = Laya.Byte.LITTLE_ENDIAN;//小端
this.ws.on(Laya.Event.MESSAGE, this, this.onMessage);
this.ws.on(Laya.Event.OPEN, this, this.onOpen);
this.ws.on(Laya.Event.CLOSE, this, this.onClose);
this.ws.on(Laya.Event.ERROR, this, this.onError);
}
onMessage(message){
console.log("WebSocket onMessage", message);
}
onOpen(event){
console.log("WebSocket onOpen", event);
}
onClose(event){
console.log("WebSocket onClose", event);
}
onError(error){
console.log("WebSocket onError", error);
}
connect(host, port){
if(!port){
// ws://localhost:8989”
this.ws.connectByUrl(host);
}else{
this.ws.connect(host, port);
}
return this;
}
close(){
this.ws.close();
}
destroy(){
this.ws.offAll();
this.ws.cleanSocket();
this.ws = null;
}
send(data){
this.ws.send(data);
return this;
}
}