
读取后websocket ping,根据此数据帧的类型进行不同的回调
private void decodeFrames(ByteBuffer socketBuffer) {
try {
List frames = this.draft.translateFrame(socketBuffer);//读取二进制流
for (Framedata f : frames) {
if (DEBUG)
System.out.println("matched frame: " + f);
Framedata.Opcode curop = f.getOpcode();
boolean fin = f.isFin();
if (curop == Framedata.Opcode.CLOSING) { //关闭帧
int code = 1005;
String reason = "";
if ((f instanceof CloseFrame)) {
CloseFrame cf = (CloseFrame) f;
code = cf.getCloseCode();
reason = cf.getMessage();
}
if (this.readystate == WebSocket.READYSTATE.CLOSING) {
closeConnection(code, reason, true);
} else if (this.draft.getCloseHandshakeType() == Draft.CloseHandshakeType.TWOWAY)
close(code, reason, true);
else {
flushAndClose(code, reason, false);
}
} else if (curop == Framedata.Opcode.PING) { //Ping
this.wsl.onWebsocketPing(this, f);
} else if (curop == Framedata.Opcode.PONG) { //Pong
this.wsl.onWebsocketPong(this, f);
} else if ((!fin) || (curop == Framedata.Opcode.CONTINUOUS)) { //分片消息
if (curop != Framedata.Opcode.CONTINUOUS) {
if (this.current_continuous_frame_opcode != null)
throw new InvalidDataException(1002, "Previous continuous frame sequence not completed.");
this.current_continuous_frame_opcode = curop;
} else if (fin) {
if (this.current_continuous_frame_opcode == null)
throw new InvalidDataException(1002, "Continuous frame sequence was not started.");
this.current_continuous_frame_opcode = null;
} else if (this.current_continuous_frame_opcode == null) {
throw new InvalidDataException(1002, "Continuous frame sequence was not started.");
}
try {
this.wsl.onWebsocketMessageFragment(this, f);
} catch (RuntimeException e) {
this.wsl.onWebsocketError(this, e);
}
} else { //普通消息
if (this.current_continuous_frame_opcode != null)
throw new InvalidDataException(1002, "Continuous frame sequence not completed.");
if (curop == Framedata.Opcode.TEXT) //文本消息
try {
this.wsl.onWebsocketMessage(this, Charsetfunctions.stringUtf8(f.getPayloadData()));
} catch (RuntimeException e) {
this.wsl.onWebsocketError(this, e);
}
else if (curop == Framedata.Opcode.BINARY) //二进制消息
try {
this.wsl.onWebsocketMessage(this, f.getPayloadData());
} catch (RuntimeException e) {
this.wsl.onWebsocketError(this, e);
}
else
throw new InvalidDataException(1002, "non control or continious frame expected");
}
}
} catch (InvalidDataException e1) {
this.wsl.onWebsocketError(this, e1);
close(e1);
return;
}
}
现在讨论控制帧的处理. WebSocket控制框架有三种类型: 关闭,乒乓和乒乓. 关闭框很容易理解. 如果客户端收到连接,则将其关闭. 客户端还可以向服务器发送关闭帧. Ping和Pong是websocket的心跳. 它们用于确保客户端. 通常,只有服务器发送ping到客户端,客户端发送Pong进行响应,表明它仍处于联机状态.
让我们看看Nathan Rajlich的Java Websocket代码. 客户端对Ping的处理非常简单. 将收到的Ping帧更改为操作码类型,然后将其发送回服务器. 您可以看到客户端处理服务器发送的Pong回调的方法为空.
public void onWebsocketPing(WebSocket conn, Framedata f) {
FramedataImpl1 resp = new FramedataImpl1(f);
resp.setOptcode(Framedata.Opcode.PONG);
conn.sendFrame(resp);
}
public void onWebsocketPong(WebSocket conn, Framedata f) {
}
本文暂时是本文,下一篇是关于Websocket客户端和Websocket服务器的实现
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/ruanjian/article-155608-2.html
宣布独立试试
>美帝胆敢违反国际法