通过socket,实现简易版的通讯
一 socket和ajax的区别:
基于的协议不同
ajax基于http协议,单项,实时获取数据,只能轮循
socket是基于事件的,实时双向通信的库,后端可以主动推送数据。在使用socket的时候,会使用很多事件。。
二 socket分类
分为三类:websocket socket.io net
三 实现通讯的案例【聊天室】
1.websocket实现简易版多人聊天通讯
注意:连接的时候,端口号一定要对应,否则无法聊天。且在聊天的时候,需要开同一个服务,可以通过node或者是gulp搭建。
wsClient.js文件:
const ws = new WebSocket('ws://10.9.70.186:3000'); //websocket是基于ws协议的// 连接ws.onopen = function () { //进入聊天室,进入到ws://127.0.0.1:3000,就会触发这个事件ws.send('大家好');}ws.onmessage = function (event) {console.log('服务端发送的信息:' + event);document.querySelector('#chatroom').innerHTML += event.data + '<br/>'}ws.onclose = function () {alert('服务端关闭了');}ws.onerror = function (err) {alert(err);}function say() {ws.send(sendInput.value);sendInput.value = '';}document.onkeyup = function (e) { //绑定一个回车事件// e = e || e.event;if (event.keyCode == 13) {say();}}sendBtn.onclick = function () {say();}
wsServer.js文件
const WebSocketServer = require('ws').Server; //ws指的就是websocket 拿到里面的服务
const wss = new WebSocketServer({ port: 3000 }); //创建服务
const clientMap = {}; //装载用户信息
var i = 0;// 创建连接
wss.on('connection', ws => {
console.log('有人进来了');
ws.name = ++i; //用来起名字
clientMap[ws.name] = ws; //收集用户信息// 获取客户端发送过来的数据
ws.on('message', data => {
console.log('客户端发送过来的数:' + data);
broadcast(data, ws); //广播信息
})// 用户离开了
ws.on('close', _ => {
delete clientMap[ws.name];
console.log(ws.name + '下线了');
})// 错误
ws.on('error', err => {
console.log(err);
ws.end();
})
})function broadcast(data, ws) { //ws代表的每个人 data代表的是说的话 把某个人的话告诉当前上线的所有人
for (var key in clientMap) {
clientMap[key].send(ws.name + '说:' + data);
}
}
2.socketIo实现简易版的通讯
需要下载socket.io.js文件
index.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>Document</title><style>.container {width: 600px;height: 400px;margin: 50px auto;}
#chatroom {overflow-y: auto;}</style></head>
<body><div class="container"><h2>docket.io</h2><div id="chatroom" style="width: 500px;height: 300px;border: 1px solid #f00;"></div><input type="text" id="sendInput" /><button id="sendBtn">提交</button></div><script src="./socket.io.js"></script><script>let ioSocket = io.connect('http://127.0.0.1:3000'); //这里的io是我们从库里面引入进来的,在这里直接使用ioSocket.on('connect',_=>{ioSocket.send('大家好');})ioSocket.on('message', data => {document.querySelector('#chatroom').innerHTML += data + '<br/>';})ioSocket.on('error', err => {alert(err);})ioSocket.on('close', _ => {alert('close');})function say() {ioSocket.send(sendInput.value);sendInput.value = '';}document.onkeyup = function (e) {if (e.keyCode === 13) {say();}}sendBtn.onclick = function () {say();}</script></body></html>
serverIo.js文件【此文件是通过koa来开服务的】
const Koa = require('koa');
const app = new Koa();
const Router = require('koa-router');
const server = require('http').createServer(app.callback()); //创建服务的时候,传入一个app的回调
const io = require('socket.io')(server); //将socket.io和server做关联 实现koa和socket.io的协同
const fs = require('fs');const router = new Router();
const clientMap = {};
let i = 0;
app.use(router.routes()).use(router.allowedMethods());router.get('/', ctx => {
function callback(data) {
ctx.body = data.toString();
}
fs.readFile('./index.html', (err, files) => {
if (err) {
console.log(err);
callback('文件未找到');
} else {
callback(files);
}
})
})
io.on('connection', client => {
console.log('有人进来了');
client.name = ++i;
clientMap[client.name] = client;client.on('message', data => {
console.log('客户端传递过来的数据:' + data);
broadcast(data, client);
})client.on('error', err => {
console.log(err);
})client.on('close', _ => {
delete clientMap[client.name];
})
})function broadcast(data, client) {
for (var key in clientMap) {
clientMap[key].send(client.name + "说:" + data);
}
}server.listen(3000);
3.net实现简易版的通讯
netClient.js
const net = require('net');// 这是客户端连接socket的方式const client = new net.Socket();client.setEncoding = 'utf-8'; //设置编码集
// 连接服务器client.connect('3000', '127.0.0.1', _ => { //端口号必须对应client.write('大家好'); //write是用来发送信息的});
// 获取服务端发送的数据client.on('data', data => {console.log('服务端发送:' + data);say(); //发送数据})
// 错误信息client.on('error', err => {console.log('err' + err);})
// 服务端关闭了client.on('end', _ => {console.log('end');})
// 发送数据,我们需要在命令行中写东西,所以要引用node的标准的输入输出流 readlineconst readline = require('readline');
const r1 = readline.createInterface({ //创建一个接口 用来做输入输出input: process.stdin,output: process.stdout})
function say() { //要使用标准的输入输出,在终端里面起一个让我们去输入的东西r1.question('请输入:', inputStr => {if (inputStr != 'bye') {client.write(inputStr + '\n');} else {//关闭客户端client.distory();//关闭标准的输入输出r1.close();}});}
netServer.js
// 引入node核心模块const net= require('net'); //它是基于node的,node已经安装在全局,所以,我们可以直接是哦用netconst chatServer = net.createServer(); //用net创建服务const clientMap = {}; //存储用户信息let i =0; //用来每次进入人的时候,给用户起名
//创建连接chatServer.on('connection',client=>{ //在socket里面,所有监听都是通过on来接收 与用户进行连接console.log('有人进来了');client.name = ++i; //给每个进入的用户起名字clientMap[client.name] = client; //将用户的信息放入clientMap对象里面,值为client
// 获取用户发送的数据client.on('data',data=>{console.log('用户发送的信息:'+data);// 将用户发送的信息,告诉其他人broadcast(data,client); //第一个参数是广播的东西,第二个参数是要发送哪一个用户传递过来的数据})
// 获取用户离开client.on('close',data=>{broadcast(data,client);delete clientMap[client.name]; //用户离开,将当前用户,从用户列表中删除})
// 获取错误信息client.on('error',err=>{console.log(err);client.end(); //有错误,连接结束})});
// 给所有用户广播消息的方法function broadcast(data,client) {for(var key in clientMap) {// write是用来发送消息clientMap[key].write(client.name+'说'+data);}}
// 起服务chatServer.listen(3000,_=>{console.log('http://localhost:3000');});