代码拉取完成,页面将自动刷新
应用示例:
SocketD.createServer("sd:ws")
.listen(new EventListener()
.doOnOpen(s->{s.handshake().outMeta("test","1")})
)
.open();
应用示例:
SocketD.createClient("sd:ws://127.0.0.1")
.config(c => c
.heartbeatInterval(1000*5)
.fragmentSize(1024 * 1024)
.metaPut("test","1"))
.connectHandler(c=> {
console.log("connect begin...");
return c.connect();
})
.open();
接配置名 | 新配置名 | 备注 |
---|---|---|
maxThreads | exchangeThreads | 交换线程数,用于消息接收等(原来的名字,语义不明) |
coreThreads | codecThreads | 解码线程数,用于编解码等(原来的名字,语义不明) |
/ | ioThreads | Io线程数,用于连接等 |
sequenceMode | sequenceSend | 有锁顺序发送(原来的名字,语义不明) |
/ | nolockSend | 无锁发送 |
备注:关于线程配置,在不同的适配时使用情况不同。其中 exchange 支持直接配置线程池(以支持 jdk21 的虚拟线程池)
接配置名 | 新配置名 | 备注 |
---|---|---|
maxThreads | exchangeThreads | 交换线程数,用于消息接收等(原来的名字,语义不明) |
coreThreads | codecThreads | 解码线程数,用于编解码等(原来的名字,语义不明) |
/ | ioThreads | Io线程数,用于连接等 |
备注:关于线程配置在 js 里,基本没用到
安全退出集群机制
//通知要开始关闭了(集群相关方不会再发消息进来)
session.closeStarting();
//等5秒,结束正在处理的消息
sleep(5_000)
//正试关闭
session.close();
安全退出集群机制
//通知要开始关闭了(集群相关方不会再发消息进来)
session.closeStarting();
//等5秒,结束正在处理的消息
sleep(5_000)
//正试关闭
session.close();
for Node.js demo
{
"name": "demo",
"description": "socket.d for node.js demo",
"author": "noear",
"dependencies": {
"@noear/socket.d": "2.3.9",
"ws": "^8.16.0"
}
}
const {SocketD} = require('@noear/socket.d');
async function main() {
let clientSession = await SocketD.createClient('sd:ws://127.0.0.1:8602/?u=a&p=2')
.config(c => c.fragmentSize(1024 * 1024))
.listen(SocketD.newEventListener().doOnMessage((s, m) => {
console.log('收到推送', m.dataAsString());
}))
.open();
clientSession.sendAndRequest("/demo", SocketD.newEntity('hello')).thenReply(reply => {
console.log('reply', reply);
});
}
main();
const {SocketD} = require('@noear/socket.d');
function main(){
let server = SocketD.createServer("sd:ws")
.config(c=>c.port(8602).fragmentSize(1024 * 1024))
.listen(buildListener())
.start();
}
function buildListener() {
return SocketD.newEventListener()
.doOnOpen(s => {
console.info("onOpen: " + s.sessionId());
}).doOnMessage((s, m) => {
console.info("onMessage: " + m);
}).doOn("/demo", (s, m) => {
if (m.isRequest()) {
s.reply(m, SocketD.newEntity("me to!"));
}
if (m.isSubscribe()) {
let size = m.rangeSize();
for (let i = 1; i <= size; i++ ) {
s.reply(m, SocketD.newEntity("me to-" + i));
}
s.replyEnd(m, SocketD.newEntity("welcome to my home!"));
}
}).doOn("/upload", (s, m) => {
if (m.isRequest()) {
let fileName = m.meta(SocketD.EntityMetas.META_DATA_DISPOSITION_FILENAME);
if (fileName) {
s.reply(m, SocketD.newEntity("no file! size: " + m.dataSize()));
} else {
s.reply(m, SocketD.newEntity("file received: " + fileName + ", size: " + m.dataSize()));
}
}
}).doOn("/download", (s, m) => {
if (m.isRequest()) {
let fileEntity = SocketD.newEntity("...");//todo://SocketD.newEntity(fs.readFileSync("/Users/noear/Movies/snack3-rce-poc.mov"));
s.reply(m, fileEntity);
}
}).doOn("/push", (s, m) => {
if (s.attrHas("push")) {
return;
}
s.attrPut("push", "1");
for (let i = 0; i++; i < 100) {
if (s.attrHas("push") == false) {
break;
}
s.send("/push", SocketD.newEntity("push test"));
//todo:sleep
}
}).doOn("/unpush", (s, m) => {
s.attrMap().remove("push");
})
.doOnClose(s => {
console.info("onClose: " + s.sessionId());
}).doOnError((s, err) => {
console.warn("onError: " + s.sessionId());
});
}
main();
//如果不能连接正常返回(由心跳尝试不断连接)
let session = SocketD.createClient("sd:tcp://127.0.0.1:8602/?token=1b0VsGusEkddgr3d")
.open();
//如果不能连接则异常
let session = SocketD.createClient("sd:tcp://127.0.0.1:8602/?token=1b0VsGusEkddgr3d")
.openOrThow();
//doOf 返回自己
new PathListener().doOf("/admin", new EventListener().doOnOpen(s->{}));
//of 返回 EventListener
new PathListener().of("/admin").doOnOpen(s->{});