效果图
信令服务器
在端到端之间传递媒体相关信息
在端到端之间传递网络相关信息
在端到端之间传递相关操作等
使用类库 socket.io
最主要的是
1 有房间概念
2 跨平台 跨终端 垮语言
Socket.io 相关用到API
Socket.io 服务端
socket.emit(); //给本次连接发送消息
io.in(room).emit()//房间内所有人
socket.to(room).emit();//除自己之外
socket.broadcast.emit();//除自己,全部站点
Sccket.io 客户端消息处理
当服务端发送一个消息一个命令的时候
socket.emit('action')
客户端接收消息 并且处理消息
socket.on('action',function(){
...})
当服务端发送一个消息一个命令的时候 还有数据的时候
socket.emit('action',arg1,x)
客户端接收消息 并且处理消息
socket.on('action',function(arg1,x){
...})
```cpp
当服务端发送一个消息一个命令的时候 还有数据 包含回调函数的时候
socket.emit('action',arg1func(x,y,..))
客户端接收消息 并且处理消息
socket.on('action',function(arg1,fn){
fn(a,b)...})
### 源码讲解
```cpp
!!! socket.io 我用的是2.x 的 需要require 3.x 以后有变化
首先绑定对应端口 我有自己域名和证书用的https 也可以http
var https_server = https.createServer(options, app);
var io = socketIo.listen(https_server);
用户进去聊天室和连接操作 connect 会在没有房间的时候创建房间 (提前设定好基础操作)
io.sockets.on('connection', (socket)=>{
socket.on('join', (room)=> {
socket.join(room);
var myRoom = io.sockets.adapter.rooms[room];
var users = Object.keys(myRoom.sockets).length;
logger.log('the number of user in room is: ' + users);
// socket.emit("joined",room,socket.id);//给自己
// socket.to(room).emit('joined', room, socket.id);//除自己之外
// io.in(room).emit('joined', room, socket.id)//房间内所有人
// socket.broadcast.emit('joined', room, socket.id);//除自己,全部站点
});
用户离开聊天室操作 (提前设定好基础操作)
socket.on('leave', (room)=> {
var myRoom = io.sockets.adapter.rooms[room];
var users = Object.keys(myRoom.sockets).length;
//users - 1;
logger.log('the number of user in room is: ' + (users-1));
socket.leave(room);
socket.to(room).emit('bye', room, socket.id)//房间内所有人,除自己外
socket.emit('leaved', room, socket.id);
//socket.to(room).emit('joined', room, socket.id);//除自己之外
//io.in(room).emit('joined', room, socket.id)//房间内所有人
//socket.broadcast.emit('joined', room, socket.id);//除自己,全部站点
});
基础HTML
这个很简单 几个butten 几个textarea 提供给输入输出用
<html>
<head>
<title>聊天室</title>
<link rel="stylesheet" href="css/main.css"></link>
<script src="js/client.js"></script>
</head>
<body>
<table align="center">
<tr>
<td>
<label>UserName: </label>
<input type=text id="username"></input>
</td>
</tr>
<tr>
<td>
<label>room: </label>
<input type=text id="room"></input>
<button id="connect">Conect</button>
<button id="leave" disabled>Leave</button>
</td>
</tr>
<tr>
<td>
<label>Content: </label><br>
<textarea disabled style="line-height: 1.5;" id="output" rows="10" cols="100"></textarea>
</td>
</tr>
<tr>
<td>
<label>Input: </label><br>
<textarea disabled id="input" rows="3" cols="100"></textarea>
</td>
</tr>
<tr>
<td>
<button id="send">Send</button>
</td>
</tr>
</table>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
<script src="js/client.js"></script>
</body>
</html>
JS主要业务代码
初始化和butten 绑定
var userName = document.querySelector('input#username');
var inputRoom = document.querySelector('input#room');
var btnConnect = document.querySelector('button#connect');
var btnLeave = document.querySelector('button#leave');
var outputArea = document.querySelector('textarea#output');
var inputArea = document.querySelector('textarea#input');
var btnSend = document.querySelector('button#send');
var socket;
var room;
发送和离开 点击操作
btnSend.onclick = ()=>{
var data = inputArea.value;
data = userName.value + ':' + data;
socket.emit('message', room, data);
inputArea.value = '';
}
btnLeave.onclick = ()=>{
room = inputRoom.value;
socket.emit('leave', room);
}
```连接聊天室相关操作 连接以后设定一堆消息处理机制
```cpp
btnConnect.onclick = ()=>{
//connect
socket = io.connect();
//send message
room = inputRoom.value;
socket.emit('join', room);
//recieve message
socket.on('joined', (room, id) => {
btnConnect.disabled = true;
btnLeave.disabled = false;
inputArea.disabled = false;
btnSend.disabled = false;
});
socket.on('leaved', (room, id) => {
btnConnect.disabled = false;
btnLeave.disabled = true;
inputArea.disabled = true;
btnSend.disabled = true;
socket.disconnect();
});
socket.on('message', (room, id, data) => {
outputArea.scrollTop = outputArea.scrollHeight;//窗口总是显示最后的内容
outputArea.value = outputArea.value + data + '\r';
});
socket.on('disconnect', (socket)=>{
btnConnect.disabled = false;
btnLeave.disabled = true;
inputArea.disabled = true;
btnSend.disabled = true;
});
}```
### 全部JS代码
```cpp
'use strict'
//
var userName = document.querySelector('input#username');
var inputRoom = document.querySelector('input#room');
var btnConnect = document.querySelector('button#connect');
var btnLeave = document.querySelector('button#leave');
var outputArea = document.querySelector('textarea#output');
var inputArea = document.querySelector('textarea#input');
var btnSend = document.querySelector('button#send');
var socket;
var room;
btnConnect.onclick = ()=>{
//connect
socket = io.connect();
//recieve message
socket.on('joined', (room, id) => {
btnConnect.disabled = true;
btnLeave.disabled = false;
inputArea.disabled = false;
btnSend.disabled = false;
});
socket.on('leaved', (room, id) => {
btnConnect.disabled = false;
btnLeave.disabled = true;
inputArea.disabled = true;
btnSend.disabled = true;
socket.disconnect();
});
socket.on('message', (room, id, data) => {
outputArea.scrollTop = outputArea.scrollHeight;//窗口总是显示最后的内容
outputArea.value = outputArea.value + data + '\r';
});
socket.on('disconnect', (socket)=>{
btnConnect.disabled = false;
btnLeave.disabled = true;
inputArea.disabled = true;
btnSend.disabled = true;
});
//send message
room = inputRoom.value;
socket.emit('join', room);
}
btnSend.onclick = ()=>{
var data = inputArea.value;
data = userName.value + ':' + data;
socket.emit('message', room, data);
inputArea.value = '';
}
btnLeave.onclick = ()=>{
room = inputRoom.value;
socket.emit('leave', room);
}
inputArea.onkeypress = (event)=> {
//event = event || window.event;
if (event.keyCode == 13) {
//回车发送消息
var data = inputArea.value;
data = userName.value + ':' + data;
socket.emit('message', room, data);
inputArea.value = '';
event.preventDefault();//阻止默认行为
}
}