不为别的,只为做一个连自己都羡慕的人

通过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的标准的输入输出流 readline
const 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已经安装在全局,所以,我们可以直接是哦用net
const 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');
}); 
posted @ 2020-01-15 17:25  升级打怪  阅读(306)  评论(0编辑  收藏  举报