前面两篇websocket的文章主要是讲的是springboot后端的开发,而前端这块还是用的原生状态下的代码,在实际应用中肯定是不会这样简单去写的,需要考虑到在不同项目中可以复用,以及可能在同一个项目里有多个功能都需要用到websocket ,那就更要考虑统一和复用了,否则每个程序员都按照自己的想法去写,后期维护将是一件很麻烦的事情,而且也无法保证程序的安全性。
第一篇博文里的前端代码
var socket;
function openSocket() {
if(typeof(WebSocket) == "undefined") {
console.log("您的浏览器不支持WebSocket");
}else{
console.log("您的浏览器支持WebSocket");
//实现化WebSocket对象,指定要连接的服务器地址与端口 建立连接
var fromId = document.getElementById('fromId').value;
var socketUrl="ws://127.0.0.1/socketweb/webSocket/"+fromId;
console.log(socketUrl);
if(socket!=null){
socket.close();
socket=null;
}
socket = new WebSocket(socketUrl);
//打开事件
socket.onopen = function() {
console.log("websocket已打开");
//socket.send("这是来自客户端的消息" + location.href + new Date());
};
//获得消息事件
socket.onmessage = function(msg) {
var serverMsg = "收到服务端信息:" + msg.data;
console.log(serverMsg);
var message=JSON.parse(msg.data);
var node=document.createElement("LI");
var textnode=document.createTextNode(message.content);
node.appendChild(textnode);
document.getElementById("cont").appendChild(node);
};
//关闭事件
socket.onclose = function() {
console.log("websocket已关闭");
};
//发生了错误事件
socket.onerror = function() {
console.log("websocket发生了错误");
}
}
}
//发送消息
function sendMessage() {
if(typeof(WebSocket) == "undefined") {
console.log("您的浏览器不支持WebSocket");
}else {
// console.log("您的浏览器支持WebSocket");
var fromId = document.getElementById('fromId').value;
var toId = document.getElementById('toId').value;
var content = document.getElementById('content').value;
var jsonMsg={fromId:fromId,toId:toId,content:content,sendMsgType:"dialog"};
console.log(jsonMsg);
socket.send(JSON.stringify(jsonMsg));
}
}
从上面的代码可以看出,socket主要流程其实就3个步数:
- 打开socket(连接socket)
- 发送消息
- 处理接收到的消息
那么我们封装遵循的原则主要也是这3个功能流程。
先上最终的效果
为了方便前端的开发,我们引入jquery。封装后的使用代码如下。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket</title>
<script src="http://127.0.0.1/socket/jquery.min.js"></script>
<script src="http://127.0.0.1/socket/socket.js"></script>
</head>
<body>
<h3>hello socket</h3>
<p>【fromId】:<div><input id="fromId" name="fromId" type="text" value="google"></div>
<p>【toId】:<div><input id="toId" name="toId" type="text" value="firefox"></div>
<p>【内容】:<div><textarea id="content" name="content" style="width:400px;height:200px;"></textarea></div>
<p>【操作】:<input type="button" id="open" value="开启socket" />
<p>【操作】:<input type="button" id="sendMsg" value="发送消息" />
<ul id="cont"></ul>
</body>
<script type="text/javascript">
$(function(){
var socket =null;
$("#open").click(function(){
var fromId = $("#fromId").val();
var socketUrl="ws://127.0.0.1/socketweb/webSocket/"+fromId;
socket = new HnWebSocket(socketUrl,true,receiveMsgFun);
});
$("#sendMsg").click(function(){
var fromId = $("#fromId").val();
var toId = $("#toId").val();
var content = $("#content").val();
var messageJson ={fromId:fromId,toId:toId,content:content}
socket.sendMessage(JSON.stringify(messageJson));
});
})
function receiveMsgFun(message){
$("#cont").append("["+message.createDateTime+"]"+message.content +"<br>");
}
</script>
</html>
效果图如下
从上面的代码看,其实主要就是对应3个流程
1:连接后端socket
socket = new HnWebSocket(socketUrl,true,receiveMsgFun);
参数: socketUrl :后端的socket地址
true : 是否自动连接
receiveMsgFun : 处理收到信息的方法
2:发送消息
socket.sendMessage(JSON.stringify(messageJson));
3:自定义消息处理方法
function receiveMsgFun(message)
最终封装的JS代码
class HnWebSocket{
/**
* 构造函数
* @param url 路径
* @param isAutoConnect 是否自动连接 true/false
* @param receiveMsgFun 接收消息后处理函数
*/
constructor(url,isAutoConnect,receiveMsgFun) {
this.socket=null;
this.url=url;
this.isSupport=typeof(WebSocket) != "undefined";//浏览器是否支持socket
if(!this.isSupport){
alert("你的浏览器不支持此功能,请使用最新版本的谷歌、火狐浏览器!");
}else if(isAutoConnect){
console.log("自动打开websocket");
this.init(receiveMsgFun);
}else{
console.log("需要手动打开websocket");
}
}
/**
* 初始化,连接后端socket
*
* @param receiveMsgFun 接收消息后处理函数
*/
init(receiveMsgFun){
var $this = this;
console.log("--->"+$this.url);
if($this.isSupport){
$this.receiveMsgFun=receiveMsgFun;
if($this.socket!=null){
$this.socket.close();
$this.socket=null;
}
$this.socket = new WebSocket($this.url);
//打开事件
$this.socket.onopen = function() {
console.log("websocket已打开");
};
//获得消息事件
$this.socket.onmessage = function(msg) {
var serverMsg = "收到服务端信息:" + msg.data;
console.log(serverMsg);
var message=JSON.parse(msg.data.replace(/\'/g,"\""));
if($this.isFunction($this.receiveMsgFun)){
//发现消息进入 开始处理前端触发逻辑
$this.receiveMsgFun(message);
}else{
console.log("没有消息处理函数!");
}
};
//关闭事件
$this.socket.onclose = function(e) {
console.log('websocket 断开: ' + e.code + ' ' + e.reason + ' ' + e.wasClean)
$this.init(receiveMsgFun);
};
//发生了错误事件
$this.socket.onerror = function() {
console.log("websocket发生了错误");
$this.init(receiveMsgFun);
}
}
}
/**
* 发送消息
*
* @param message 消息主题,如果是json格式需要转换成字符串
*/
sendMessage(message){
var isSend = false;
try{
if(this.isSupport){
this.socket.send(message);
isSend =true;
}
}catch(e){}
return isSend;
}
isFunction(funName){
var isFunction = false;
try{
isFunction = typeof(eval(funName))=="function";
}catch(e){}
return isFunction;
}
}
上面的代码中注释都写了,大家看看应该就清楚了,就不多说了,以上就是前端初级封装的代码,如果要再提高可用性和安全性,那还要加一些健壮性的判断,例如要判断服务器断线后重连的机制,不同浏览器断线的监测等等。这些下次再讲了。