牙叔教程 简单易学
使用场景
socketIO
socketIO
SocketIO是在客户端和服务端之间建立的双向通信数据交换技术,在即时通讯、通知与消息推送,实时分析等场景中有较为广泛的应用。
效果展示
效果.pngautojs版本
8.7.7-0
代码简介
通信是双向的, 所以既有客户端, 也有服务端
1. 服务端
使用koa框架搭建, 使用的主要模块是 "socket.io": "^4.0.1"
2. 客户端
socketIO模块依赖 implementation('io.socket:socket.io-client:2.0.0')
用android studio调试成功以后, 转成dex供给autojs使用
get知识点
-
koa搭建socketIO
-
autojs使用socketIO
-
listView的item_bind, 添加控件监听事件
-
常见的socketIO使用方法
-
多用户的管理
-
多用户的消息传递
-
添加新用户, listView自动滚动到最底部, 让新添加的用户进入视野
-
随机颜色
-
获取用户对应的socket连接
-
用户进入房间, 用户离开房间
-
用户上线, 用户下线
-
格式化时间
-
调用java的字符串格式化
-
随机字符串
-
nodemon的使用
代码讲解
服务端
1. 主脚本
io.on("connection", (socket) => {
console.log("已连接" + socket.id);
socket.on("userLogin", (userName) => {
...
});
socket.on("disconnect", function () {
...
});
socket.on("deleteUser", function (userName) {
...
});
socket.on("joinRoom", function (userName, roomName) {
...
});
socket.on("leaveRoom", function (userName) {
...
});
socket.on("chat", function (chatContent) {
...
});
});
2. nodemon启动服务, 这样代码修改了不用自己再重启了
"dev": "nodemon index.js -i README.md"
npm run dev
客户端
1. 导入socketio依赖
let dexPath = "./classes_merge.dex";
log(dexPath);
runtime.loadDex(dexPath);
2. 导入需要使用的类
importClass(Packages.io.socket.client.IO);
importClass(Packages.io.socket.client.Socket);
importClass(Packages.io.socket.emitter.Emitter);
importClass(Packages.io.socket.engineio.client.transports.Polling);
importClass(Packages.io.socket.engineio.client.transports.WebSocket);
3. UI, 一共四个页面
- 配置页面, 用于增加删除用户
- 大厅页面, 用户上线离线日志
- 房间1号日志页面. 1号房间的用户出入记录, 以及发言记录
- 2号, 3号 与1号用途类似
<vertical>
<button id="回到配置页">
回到配置页
</button>
<viewpager id="viewpager">
<vertical>
增删用户页面
</vertical>
<vertical padding="8">
大厅日志页面
</vertical>
<vertical padding="8">
房间1号日志页面
</vertical>
<vertical padding="8">
房间2号日志页面
</vertical>
<vertical padding="8">
房间3号日志页面
</vertical>
</viewpager>
</vertical>
4. 初始化用户数据
let userList = yashuUtil.getUserList();
ui.userList.setDataSource(userList);
5. 更新日志
由于更新日志的方法类似, 都是更新textView的内容, 只是viewId不一样, 所以要方法复用
function 更新日志(日志viewId, data) {
let oldContent = ui[日志viewId].text();
let newContent = oldContent + "\n" + data + yashuUtil.getTime();
ui.run(function () {
ui[日志viewId].setText(newContent);
});
}
6. 用户点击单选按钮, 来选择进入那个房间
itemView.房间列表.setOnCheckedChangeListener(function (radioGroup, id) {
let item = itemHolder.item;
let viewId = radioGroup.getCheckedRadioButtonId();
if (viewId !== -1) {
let radioView = ui.findView(viewId);
let value = radioView.getText().toString();
if (radioView.checked) {
let roomName = value;
item.socket.emit("joinRoom", item.name, roomName);
}
}
});
7. 离开房间
itemView.leave.click(function () {
itemView.房间列表.clearCheck();
let item = itemHolder.item;
item.socket.emit("leaveRoom", item.name);
});
8. 用户发言
itemView.send.click(function () {
if (itemView.chatContent.text().length < 1) {
log("聊天内容为空");
return false;
}
let item = itemHolder.item;
let user = yashuUtil.getCurrentUser(item.socket);
if (user) {
if (user.roomName) {
item.socket.emit("chat", itemView.chatContent.text() + " ");
} else {
log("用户没有加入房间");
}
} else {
log("没找到用户");
}
});
9. socket连接时, 注册监听事件
mSocket = IO.socket(baseUrl);
mSocket.on(Socket.EVENT_CONNECT, onConnect);
mSocket.on("disconnect", onDisconnect);
mSocket.on("userLogin", onUserLogin);
mSocket.on("userExit", onUserExit);
mSocket.on("joinedRoom", onJoinedRoom);
mSocket.on("leftRoom", onLeftRoom);
mSocket.on("chat", onChat);
mSocket.connect();
10. 退出时, 释放资源
events.on("exit", function () {
yashuUtil.deleteAllUser();
});
参考文章
声明
部分内容来自网络
给我个面子小图.jpg
网友评论