socket.d.js 是基於 websocket 包裝的 socket.d 協議的實現。就是用 ws 傳輸數據,但功能更強大。
功能 | 原生 websocket | socket.d | 說明 |
---|---|---|---|
listen | 有 | 有 | 監聽消息 |
send | 有 | 有 | 發消息 |
sendAndRequest | 無 | 有 | 發消息並接收一個響應(類似於 http) |
sendAndSubscribe | 無 | 有 | 發消息並接收多個響應(也叫訂閱) |
event(or path) | 無 | 有 | 消息有事件或路徑(可對消息,進行業務路由) |
meta(or header) | 無 | 有 | 消息有元信息或頭信息(可爲數據,標註業務語義) |
自動心跳 | 無 | 有 | |
斷開後自動重鏈 | 無 | 有 |
下面感受下開發方面的差異!
1、客戶端示例代碼
使用時,可以根據自己的業務對原生接口包裝,進一步簡化使用。
<script src="js/socket.d.js"></script>
<script>
async function init(){
//構建事件監聽
const eventListener = await SocketD.newEventListener().doOnMessage((s,m)=>{
//監聽所有消息(可能不需要)
}).doOn("/im/user.upline", (s,m)=>{ //事件的應用
//監聽用戶上線
let user_id = m.meta("user_id");
}).doOn("/im/user.downline", (s,m)=>{
//監聽用戶下線
let user_id = m.meta("user_id"); //元信息的應用
});
//創建單例
window.clientSession = SocketD.createClient("sd:ws://127.0.0.1:8602/?u=a&p=2")
.listen(eventListener)
.open();
}
function join(){
clientSession.sendAndRequest("/user/join", SocketD.newEntity()).thenReply(r->{
//加入成功
});
}
init();
</script>
Socket.D 有三個發消息的接口:
接口 | 說明 |
---|---|
send | 像 websocket。多了事件與元信息屬性 |
sendAndRequest | 像 http |
sendAndSubscribe | 像 reactive stream 。多了事件與元信息屬性 |
2、服務端示例代碼(用 java 演示)
public class Demo {
public static void main(String[] args) throws Throwable {
List<Session> userSessions = new ArrayList<Session>();
//創建監聽器
Listener listener = new EventListener().doOnOpen(s->{
//鑑權
if("a".equals(s.param("u")) == false){
s.close();
}else{
//加入用戶表
s.attrPut("user_id", s.param("u"));
userSessions.add(s);
}
}).doOn("/user/join", (s,m)->{
if(m.isRequest()){
s.reply(m, new StringEntity());
}
for(Session s1: userSessions){
//告訴所有用戶,有人上線
s1.send("/im/user.upline", new StringEntity().metaPut("user_id"), s.attr("userId"));
}
});
//啓動服務
SocketD.createServer("sd:ws")
.config(c -> c.port(8602))
.listen(listener)
.start();
}
}
3、Socket.D 是什麼東東?
Socket.D 是一個基於“事件”和“語義消息”“流”的網絡應用層協議(聽起來好像很 ao 口)。支持 tcp, udp, ws, kcp 傳輸(有各種不同語言的實現)。有用戶說,“Socket.D 之於 Socket,尤如 Vue 之於 Js、Mvc 之於 Http”。
協議之所有強大,有三個關鍵基礎因素:
- 事件
- 語義消息
- 流
它的幀碼結構:
[len:int][flag:int][sid:str(<64)][\n][event:str(<512)][\n][metaString:str(<4k)][\n][data:byte(<16m)]
因爲是應用層協議,所以可以建立在任意傳輸層協議之上。比如 websocket。