koa2中增加websocket(使用socket.io)
能力有限不知道如何把socket加入koa2的路由,只好走socket.io的namespace,path默认为 wss://localhost/socket.io/(我用的是https所以协议是wss)
www文件内添加代码
/***
*WWW文件原内容
**/
// 把https封装成io对象,tagServerA 为原 koa http/https 服务,由服务对象不同会自己转为 ws/wss
const socketio = require('socket.io')(tagServerA);
const adminNamespace = socketio.of('/chatsocket');//设置namespace 管理websocket
adminNamespace.use((socket, next) => {
next();
});
//链接计数器 因为用户数据不落地 所以用计数器做key
let connectionCount = 0;
adminNamespace.on('connection', function (socket) {
// 给每个用户取名字
connectionCount++
socket.nickname = "";
socket.index = connectionCount;
// adminNamespace.emit代表在对应namespace下广播,socket.emit代表私发,连接归谁就发给谁;客户端添加了链接后发送setname事件设置昵称 所以要加一个接收事件
socket.on('setname', function (str) {
socket.nickname = str + "(" + socket.index + ")";
adminNamespace.emit('enter', socket.nickname + ' 进入房间');//设置好昵称后通知当前namespace里的用户有新人加入
})
//发送消息广播 走message事件 socket.io是事件处理 只要名字约定好了 叫啥都行
socket.on('message', function (str) {
adminNamespace.emit('message', socket.nickname + ' 说: ' + str)
})
// 客户端断开,自带事件
socket.on('disconnect', function () {
adminNamespace.emit('leave', socket.nickname + ' 离开房间')
})
})
html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>找不到来源的消息</title>
<!-- cdn -->
<script src="/res/lib/socket.io.js"></script>
</head>
<body>
<h1>匿名消息</h1>
<div id="setnickdiv">
<input id="nicktext" type="text" placeholder="设置昵称" />
<button id="sendnick">保存</button>
</div>
<div id="senddiv" style="display:none;">
<input id="sendTxt" type="text" />
<button id="sendBtn">发送</button>
</div>
<div id="recv"></div>
<script type="text/javascript">
//hostname后面为namespace 下面的链接 namespace为 chatsocket
let wxurl = window.location.protocol + "//" + window.location.hostname + "/chatsocket";
let sendBtn = document.getElementById("sendBtn");
let sendText = document.getElementById("sendTxt");
let nicktext = document.getElementById("nicktext");
let sendnick = document.getElementById("sendnick");
let socket = {};
//本地是否有昵称记录 有就直接初始化socket
if (window.localStorage.getItem("nickname")) {
document.getElementById("setnickdiv").style = "display:none;";
document.getElementById("senddiv").style = "display:block"
nicktext.value = window.localStorage.getItem("nickname");
socketInit();
}
//保存昵称
sendnick.onclick = function () {
if (nicktext.value) {
window.localStorage.setItem("nickname", nicktext.value);
document.getElementById("setnickdiv").style = "display:none;";
document.getElementById("senddiv").style = "display:block"
socketInit();
} else {
alert("昵称不能为空")
}
}
//把接收的数据显示到界面
function showMessage(str, type) {
console.log(str, type);
var div = document.createElement('div');
div.innerHTML = str;
if (type == "enter") {
div.style.color = 'blue';
} else if (type == "leave") {
div.style.color = "red"
}
document.body.appendChild(div)
}
// 点击之后发送
sendBtn.onclick = function () {
var txt = sendText.value;
if (txt) { // 消息不能为空
socket.emit('message', txt);
sendText.value = "";
}
}
//回车发消息
sendText.addEventListener("keyup", function (event) {
if (event.keyCode == 13) {
sendBtn.click()
}
})
function socketInit() {
socket = io(wxurl, { transports: ['websocket'] });
//发送昵称
socket.emit('setname', nicktext.value);
// 服务端每链接一个websocket 就会触发一次enter enter消息用于显示进入人员
socket.on('enter', function (data) {
showMessage(data, 'enter')
})
socket.on('message', function (data) {
showMessage(data, 'message')
})
socket.on('leave', function (data) {
showMessage(data, 'leave')
})
}
</script>
</body>
</html>