1.socket(链接的一方的终端)
因为要进行聊天程序的开发,就需要后台服务器实时监控,而http是非持久性的链接,所以要用socket(持久性的链接)。
聊天软件的开发逻辑:
一.A发送消息--->服务端
A要发送消息,首先要有客户端,就是A
1.const net = require("net")----因为要建立持久性的链接,所以用net模块
2.const readline = require("readline")----引入可以在终端读写的模块
3.const client = new net.Socket()----创建客户端,用socket构造
4.const rl = readline.createInterface({----建立终端输入和输出,完成在终端可以读写的功能
input:process.stdin,----终端输入
output:process.stdout----终端输出
})
5.client.setEncoding("utf8")----将接受的服务端的buffer文件转换为字符串
5.client.connect(9000,"127.0.0.1",()=>{----链接服务端,参数一:是服务端的端口号,参数二:自己的ip地址
client.on("data",(data)=>{----接受服务端传递过来的信息
cosole.log(data)----输出信息
})
})
6.rl.on("line",(text)=>{----可以让用户在终端上对文件进行读写操作
client.write(text)----向服务端发送消息
})
二.服务端接收到消息后--->会给所有的链接的用户发送这个消息
服务端要接受A发的消息,首先要建立服务端
1. const net = require("net")----因为要建立持久性的链接,所以用net模块
2. const server = net.createServer()---创建服务端
3. server.listen(9000)----设置端口号9000
4. consrt clients = []----创建一个空数组,用来存储所有的链接此服务端的用户
5. server.on("connection",(client)=>{----当用户链接到服务端以后
client.id = client.length;----给进来的用户一个唯一的id以便以后他断开链接的时候,排除他
clients.push(client);----将链接的用户添加到数组,存储区起来
console.log("a user connect")----当有人链接进来的时候,服务端自己的提示信息
6.client.on("data",(data)=>{----接收客户端发送过来的消息,存入data里面
clients.map((item)=>{----遍历链接的用户的数组
if(item){----如果该用户存在
item.write(data)----将从客户端接收的消息发送给所有链接服务端的客户端,包括发送此消息的客户端
}
}
})
})
三.如果有的用户断开链接了那么就不用给他发消息了
client.on("close",()=>{----用close来检测客户端断开链接
clients[client.id] = null;----让断开链接的那个id为空
})
2.webSocket(可以让用户在页面上进行聊天,存在兼容问题)
一:客户端
<!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>
</head>
<body>
<input type="text" id="msg">
<button id="btn">发送</button>
<ul id="list"></ul>
</body>
</html>
<script>
//链接服务端
var client = new WebSocket("ws://127.0.0.1:9000"); //兼容性有问题
ip地址 链接服务端的端口号
//接收服务端的消息
client.onmessage = function (val) {
var li = `<li>${val.data}</li>`;
list.innerHTML += li;
}
//向服务端发送消息
btn.onclick = function () {
var val = msg.value;
client.send(val);
msg.value = "";
}
</script>
二、服务端
const WebSocket = require('ws');
//创建服务器 绑定端口号
const server = new WebSocket.Server({ port: 9000 });
//链接服务器
server.on('connection', (client) => {
//接收客户端传递过来的消息
client.on('message', (message) => {
console.log(message);
//将这个消息发送给所有的客户端
server.clients.map((item)=>{
if ( item.readyState === WebSocket.OPEN) {---判断客户端是否和服务端处于链接状态
item.send(message);----向服务端发送消息
}
});
});
});
3.socket.io(可以在网页上进行聊天。没有兼容问题,github上搜索有)
一:服务端
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
//当访问根路径的时候返回一个index.html文件
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
//当客户端链接进来的时候
io.on('connection', function(socket){
console.log('来了老弟');
//接收客户端传递过来的消息
socket.on('handle', function(msg){
//向所有的链接的客户端发送消息,广播效果
io.emit("serverMessage",msg)
});
//当用户离开的时候
socket.on('disconnect', function(){
console.log('走了大姐');
});
});
http.listen(3000);----端口号
二:客户端
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
form { background: #000; padding: 3px; position: fixed; bottom: 0; 100%; }
form input { border: 0; padding: 10px; 90%; margin-right: .5%; }
form button { 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }
</style>
</head>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
</body>
</html>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io();
$('form').submit(function(e){
e.preventDefault();---阻止表单默认事件
//向服务端发送消息(事件触发方式)
socket.emit('handle', $('#m').val());
$('#m').val('');----发送之后为空
return false;----阻止浏览器默认事件
});
socket.on('serverMessage', function(msg){
var li = $("<li></li>")----创建标签
$('#messages').append(li.text(msg));----标签插入内容
li[0].scrollIntoView();----让数据一直在可视窗口内
});
</script>