搭一个聊天室
WebSocket 是什么?
- 建立在 TCP 协议之上的网络通信协议
- 全双工通信协议
- 没有同源限制
- 可以发送文本、二进制数据等
NodeJS插件
目前最出色的两个插件是socket.io
和ws
浏览器连接
前端连接服务的API叫WebSocket
也可以用别人封装好的socket.io
,跟上面的NodeJS是同一家的,但是是HTML使用的
网上的代码很多,找了两份好理解的
代码一
ws插件+原生
npm install ws --save
// app.js
const PORT = 8080; // 监听端口
const WebSocket = require("ws"); // 引入 ws 库
const wss = new WebSocket.Server({ port: PORT }); // 声明wss对象
/**
* 已经连接中的用户发送数据触发
* 向除了本身之外所有客户端发送消息,实现群聊功能
* @param {*} data 要发送的数据
* @param {*} ws 客户端连接对象
*/
wss.broadcastToElse = function broadcast(data, ws) {
wss.clients.forEach(function each(client) {
if (client !== ws && client.readyState === WebSocket.OPEN) {
// 把A的话发送给除了A以外的其他人
client.send(data);
}
});
};
/* 客户端接入,触发 connection */
wss.on("connection", function connection(ws, req) {
// 通过req对象可以获得客户端信息,比如:ip,headers等
let ip = req.connection.remoteAddress;
/* 客户端发送消息,触发 message */
ws.on("message", function incoming(message) {
ws.send(message); // 向客户端发送消息
wss.broadcastToElse(message, ws); // 向 其他的 客户端发送消息,实现群聊效果
});
});
// index.html
// WebSocket是原生的,不需要插件
var userName = parseInt(Math.random() * 1000, 10) // 随机用户名, 以标识身份
var sendBtn = $("#send-btn"), // 发送信息按钮
chatInput = $("#chat-input"), // 聊天信息输入框
showArea = $("#show-area") // 聊天信息展示框
var ws = new WebSocket("ws://localhost:8080/") // 初始化WebSocket对象
sendBtn.on("click", function () {
var content = chatInput.val()
if (content.length === 0) {
return alert("请不要输入空白内容")
}
content = "At " + (new Date()).toString() + "\n" + "来自用户" + userName + "\n" + content // 拼接用户信息、时间信息和消息
ws.send(content) // 发送消息
chatInput.val("") // 清空输入框
})
// 连接时触发
ws.onopen = function () { console.log("Conncet open") }
// 接受消息触发
ws.onmessage = function (evt) {
var data = evt.data
// 刷新聊天信息展示框:显示群聊信息
showArea.val(showArea.val() + data + "\n\n")
}
ws.onclose = function () { console.log("Connect close") }
npm install express socket.io --save
// app.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var usocket = [];
app.get('/', function(req, res){
// 发送文件夹里的index.html页面
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
console.log('a user connected')
socket.on("join", function (name) {
usocket[name] = socket
io.emit("join", name)
})
socket.on("message", function (msg) {
io.emit("message", msg) //将新消息广播出去
})
});
http.listen(3000, function() {
console.log('listening on *:3000');
});
// index.html
<script src="/socket.io/socket.io.js"></script>
var name = prompt("请输入你的昵称:");
var socket = io()
//发送昵称给后端,并更改网页title
socket.emit("join", name)
document.title = name + "的群聊"
// 连接服务器
socket.on("join", function (user) {
addLine(user + " 加入了群聊")
})
//接收到服务器发来的message事件
socket.on("message", function(msg) {
addLine(msg)
})
//当发送按钮被点击时
$('form').submit(function () {
var msg = $("#m").val() //获取用户输入的信息
socket.emit("message", msg) //将消息发送给服务器
$("#m").val("") //置空消息框
return false //阻止form提交
})
function addLine(msg) {
$('#messages').append($('<li>').text(msg));
}