演示视频
视频:
- for H5
- for UniAPP
1、H5 演示地址:
前端源码可以直接看网页源码(不太好看啊)。
2、配套服务端代码 - java:
- 添加依赖
<dependency>
<groupId>org.noear</groupId>
<artifactId>socketd-transport-java-websocket</artifactId>
<version>2.5.12</version>
</dependency>
- 代码
public class ServerTest {
/**
* 启动服务,给别的客户端调试
*/
public static void main(String[] args) throws Exception {
Server server = SocketD.createServer("sd:ws")
.config(c -> c.port(8602).fragmentSize(1024 * 1024))
.listen(buildListener())
.start();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
RunUtils.runAndTry(server::stop);
}));
}
/**
* 构建监听器
*/
private static Listener buildListener() {
return new EventListener()
.doOnOpen(s -> {
System.out.println("onOpen: " + s.sessionId() + ", meta=" + s.handshake().paramMap());
}).doOnMessage((s, m) -> {
System.out.println("onMessage: " + m);
}).doOn("/demo", (s, m) -> {
if (m.isRequest()) {
s.reply(m, new StringEntity("me to! ref:" + m.dataAsString()));
}
if (m.isSubscribe()) {
int size = m.rangeSize();
for (int i = 1; i <= size; i++) {
s.reply(m, new StringEntity("me to-" + i));
}
s.replyEnd(m, new StringEntity("welcome to my home!"));
}
}).doOn("/upload", (s, m) -> {
if (m.isRequest()) {
String fileName = m.meta(EntityMetas.META_DATA_DISPOSITION_FILENAME);
if (StrUtils.isEmpty(fileName)) {
s.reply(m, new StringEntity("no file! size: " + m.dataSize()));
} else {
s.reply(m, new StringEntity("file received: " + fileName + ", size: " + m.dataSize()));
}
}
}).doOn("/download", (s, m) -> {
if (m.isRequest()) {
FileEntity fileEntity = new FileEntity(new File("/Users/noear/Movies/snack3-rce-poc.mov"));
s.reply(m, fileEntity);
}
}).doOn("/push", (s, m) -> {
if (s.attrHas("push")) {
return;
}
s.attrPut("push", "1");
while (true) {
if (s.attrHas("push") == false) {
break;
}
s.send("/push", new StringEntity("push test"));
RunUtils.runAndTry(() -> Thread.sleep(200));
}
}).doOn("/unpush", (s, m) -> {
s.attrMap().remove("push");
})
.doOnClose(s -> {
System.out.println("onClose: " + s.sessionId());
}).doOnError((s, err) -> {
System.out.println("onError: " + s.sessionId());
err.printStackTrace();
});
}
}
3、配套服务端代码 - node.js:
包配置里添加依赖(package.json)
{
"name": "demo",
"description": "socket.d for node.js demo",
"author": "noear",
"dependencies": {
"@noear/socket.d": "2.3.9",
"ws": "^8.16.0"
}
}
代码(index.js)
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();