websoket 自定义协议折中方案,适合简单数据传递,相比较json 字符串较短,转换效率更好,通过消息头可以预解析。
js 发送消息,主要解决是用 String.fromCharCode(*) 记录数据长度分段读取!比直接转json效率高3倍左右
function addMessage(obj=[]){
//消息头
var gameId = isNaN(obj[0])?parseInt(obj[0]):obj[0];
var type = isNaN(obj[1])?parseInt(obj[1]):obj[1];
var cont = obj.length - 2;//减去消息头两个下标,消息段落总数
var str = String.fromCharCode(gameId) +
String.fromCharCode(type)+String.fromCharCode(cont);
//消息体
for(var i=2; i < obj.length; i++){
var len = obj[i].length; //计算消息长度,
//加入消息数据,单个消息长度不等超过 char的长度
str += String.fromCharCode(len) + obj[i];
}
return str;
}
服务端读取,构造方法里面解析子类传递的数据,解析成数组后,交给子类读取(或者由子类继续解析字符串)
package com.zhkj.chat.entity;
/**
* 聊天消息
* @author zhkj-002
*
*/
public abstract class FriendMessage {
int gameId;
int type;
String gameVersions;
private String[] msgS;
public FriendMessage() {
super();
}
public FriendMessage(String message) {
this.gameId = message.charAt(0);
this.type = message.charAt(1);
this.msgS = getMsgS(message);
init(this.msgS);
}
public String[] getMsgS(String message) {
String[] arr = new String[message.charAt(2)];
int index = 3;
for(int i = 0; i < arr.length; i++) {
int len = message.charAt(index)+1;
arr[i] = message.substring(index + 1, index + len);
index = index + len;
}
return arr;
}
protected abstract void init(String[] message);
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getGameId() {
return gameId;
}
public void setGameId(int gameId) {
this.gameId = gameId;
}
}
子类的实例
package com.zhkj.chat.entity.chat;
import com.zhkj.chat.entity.FriendMessage;
/**
* 申请添加好友
* @author zhkj-002
*
*/
public class ApplyForFriendsMessages extends FriendMessage {
String openId;
String forOpenId;
public ApplyForFriendsMessages() {
super();
}
public ApplyForFriendsMessages(String message) {//传递父类构造
super(message);
}
@Override
protected void init(String[] message) {//解析父类解析好的数据,初始化属性
this.openId = message[0];
this.forOpenId = message[1];
}
public String getForOpenId() {
return forOpenId;
}
public void setForOpenId(String forOpenId) {
this.forOpenId = forOpenId;
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
}
消息分发,可以通过解析消息数据,大概知道这条消息的意义,不需要完全解析整条消息就知道消息的相关信息
switch (message.charAt(0)) {
//好友聊天
case 1://聊天
ReceiveMessages receiveMessages = new ReceiveMessages(message);
friendMessage.receiveMessages(receiveMessages);
break;
default://日志
logger.debug("未知消息:{}:{}", (int)message.charAt(0), (int)message.charAt(1));
break;
}