最近的项目使用了websocket来做服务端和客户端的通讯,这里记录分享一下,我是怎么做的。
什么是WebSocket?
WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。
WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
前端实例
不多废话,直接看代码
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible">
<title>websocket测试</title>
<script src="./js/jquery.min.js" type="text/javascript"></script>
<link href="./css/main.css" rel="stylesheet" />
</head>
<body style='text-align:center;margin: 40px;max-width: 1200px;'>
<div style="text-align: right;">
<input placeholder="ws://218.200.69.7:15461" id="socketURL">
<button class='pri_button' id="connectBtn" onclick="openSocket()">链接</button>
<button class='dis_button' disabled="disabled" id="closeBtn" onclick="closeSocket()">断开</button>
</div>
<div class="disDiv">
<p class="msgWindowTitle">消息窗口</p>
<div id='showDriverMSG'></div>
<div class='sendMSG'>
<textarea id='clientMSG' style="max-width: 1100px"></textarea>
<button class="dis_button" id="sendMSGBtn" disabled="disabled" onclick="sendMSG()" style="float: right; margin-left: 10px;">发送</button>
</div>
</div>
</body>
js
/*
* 连接服务器
*/
function openSocket() {
var socketURL = $('#socketURL').val();
if (socketURL == null || socketURL == '') {
socketURL = 'ws://218.200.69.7:15461/websocketServer';
}
let websocket = new WebSocket(socketURL);
websocket.onopen = function (evt) { //socket链接成功
// console.log('onopen:' + evt);
var dateStr = getNowFormatDate();
var elem = '<div class="itemMSG"><div class="machineMSG" style="color: cyan;"><p>连接成功</p><p class="timeStr">' + dateStr + '</p></div></div>'
$('#showDriverMSG').append(elem);
changeBtnState(true);
};
websocket.onclose = function (evt) { //socket关闭
changeBtnState(false);
};
websocket.onmessage = function (evt) { //接收到服务端发送的消息
var dateStr = getNowFormatDate();
var elem = '<div class="itemMSG"><div class="machineMSG"><p>服务器</p><p class="timeStr">' + dateStr + '</p></div><div style="text-align:left;">' + evt.data + '</div></div>'
$('#showDriverMSG').append(elem);
showNews(evt.data);
};
websocket.onerror = function (evt) { //连接或发送消息报错
var dateStr = getNowFormatDate();
var elem = '<div class="itemMSG"><div class="machineMSG" style="color: red;"><p>出错</p><p class="timeStr">' + dateStr + '</p></div></div>'
$('#showDriverMSG').append(elem);
changeBtnState(false);
};
window.websocket = websocket;
}
/*
* 与服务器断断开
*/
function closeSocket() {
window.websocket.close();
var dateStr = getNowFormatDate();
var elem = '<div class="itemMSG"><div class="machineMSG" style="color: red;"><p>主动关闭连接</p><p class="timeStr">' + dateStr + '</p></div></div>'
$('#showDriverMSG').append(elem);
changeBtnState(false);
}
/*
* 客户端发送数据
*/
function sendMSG() {
var ws = window.websocket;
if (!ws) {
alert('请先点击连接按钮与服务端建立连接!');
return;
}
/*
readyState表示连接有四种状态:
CONNECTING (0):表示还没建立连接;
OPEN (1): 已经建立连接,可以进行通讯;
CLOSING (2):通过关闭握手,正在关闭连接;
CLOSED (3):连接已经关闭或无法打开;
*/
if (ws.readyState == 1) {
var msg = $('#clientMSG').val();
console.log(msg);
window.websocket.send(msg);
var dateStr = getNowFormatDate();
var elem = '<div class="itemMSG"><div class="machineMSG"><p style="color:green;">本机</p><p class="timeStr" style="color:green;">' + dateStr + '</p></div><div style="text-align:left;">' + msg + '</div></div>'
$('#showDriverMSG').append(elem);
$('#clientMSG').val('');
} else {
alert('请重新连接!');
}
}
//#################工具方法
//获取当前时间,格式YYYY-MM-DD
function getNowFormatDate() {
var date = new Date();
return date.toLocaleString();
}
//连接和断开时的样式显示
function changeBtnState(isConnect) {
if (isConnect) {
$('#connectBtn').attr('class', 'dis_button');
$('#connectBtn').attr('disabled', 'true');
$('#closeBtn').attr('class', 'pri_button');
$('#closeBtn').removeAttr('disabled');
$('#sendMSGBtn').attr('class', 'pri_button');
$('#sendMSGBtn').removeAttr('disabled');
} else {
$('#connectBtn').attr('class', 'pri_button');
$('#connectBtn').removeAttr('disabled');
$('#closeBtn').attr('class', 'dis_button');
$('#closeBtn').attr('disabled', true);
$('#sendMSGBtn').attr('class', 'dis_button');
$('#sendMSGBtn').attr('disabled', true);
}
}
openSocket();
//子父窗口交互
//有新消息
function showNews(data) {
parent.getNews(data);
}
//将字符串转换成二进制形式,中间用空格隔开
strToBinary=function(str) {
let result = [];
let list = str.split("");
for (var i = 0; i < list.length; i++) {
if (i != 0) {
result.push(" ");
}
let item = list[i];
let binaryStr = item.charCodeAt().toString(2);
result.push(binaryStr);
}
return result.join("");
}
//将二进制字符串转换成Unicode字符串
binaryToStr=function(str) {
var result = [];
var list = str.split(" ");
for (var i = 0; i < list.length; i++) {
var item = list[i];
var asciiCode = parseInt(item, 2);
var charValue = String.fromCharCode(asciiCode);
result.push(charValue);
}
return result.join("");
}