刚入职没几天,就被公司老大叫来分配任务,让我做和客户那边进行双向通信的功能设计。之前没做过这个,一脸懵逼,问了技术群里的大佬,推荐我用Tomcat Socket,于是我百度查了查这个,就打算学习一下Websocket技术。
这门技术是现在做双向通信挺火的技术,那么已经用惯了HTTP通信,为什么要用Websocket呢?
不懂的可以看下面这几条技术博客讲解,我这里就不在说明原理。
http://www.ruanyifeng.com/blog/2017/05/websocket.html
https://www.zhihu.com/question/20215561
ok,等你看了上面两条链接,知道了WebSocket和HTTP不同的地方,以及用WebSocket的好处,那么你可以继续往下看。
在这里我简单说一下,WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
在WebSocket API中,浏览器和服务器实现连接的步骤,分为下面几步:
- 浏览器用HTTP协议向服务器发出建立 WebSocket 连接的请求
- 客户端和服务端连接建立之后,二者之间就会连接起一条TCP协议的通道
- 二者可以进行双向通信
这时候有人说了,TCP也是可以双向通信,但是TCP是偏底层的协议,适合和硬件打交道,而聊天室,游戏等基本上都属于软件,不和硬件打交道。
推荐WebSocket的三大理由:
- 1、采用全双工通信,摆脱传统HTTP轮询的窘境。
- 2、采用W3C国际标准,完美支持HTML5。
- 3、简单高效,容易上手
废话不多说,上依赖:
<!-- 依赖 -->
<dependencies>
<!-- Websocket依赖 -->
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
<!-- Java Servlet 依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
有两个依赖,一个是webSocket的依赖,一个是java servlet的依赖。因为websocket需要用到java的servlet技术。而tomcat自带的java servlet和websocket有点不兼容。所以这里我们不用tomcat自带的jar包。
上JS代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>my ws</title>
<script type="text/javascript" src="js/jquery-3.2.1.js"></script>
</head>
<body>
<div>
<button id="login">连接</button>
<input type="text" id="message">
<button id="send">发送</button>
</div>
<div id="showMessage">
<!-- 显示消息区 -->
</div>
</body>
<script type="text/javascript">
var ws = null;
var url = "ws://localhost:8080/myws/myws";
$('#login').click(function(){
ws = new WebSocket(url);
//和服务端连接成功时回调
ws.onopen = function(){
$('#showMessage').append("<p>连接成功</p>");
}
//接收到服务端发来的消息时回调
ws.onmessage = function(event){
$('#showMessage').append("<p>服务端:" + event.data + "</p>");
}
//通信异常时回调
ws.onerror = function(){
$('#showMessage').append("<p>出错。。。</p>");
}
});
$('#send').click(function(){
var message = $('#message').val();
//对消息进行非null校验
if(message==null || message==""){
alert("发送消息不能为空");
}else{
$('#showMessage').append("<p>" + message + "</p>");
//发送给服务端
ws.send(message);
$('#message').val('');//对消息框进行清空处理
}
});
</script>
</html>
| websocket事件函数 | 事件描述 |
| WebSocket.onopen | 和打开连接后触发 |
| WebSocket.onmessage | 接收到服务端发来的消息时触发 |
| WebSocket.onerror | 当通信异常时触发 |
| WebSocket.onclose | 当连接关闭时触发 |
其中JS中的代码:
var ws = new WebSocket(url);
这句代码就是实现和服务端连接,其中url就是你要发请求的url。
上服务端代码:
package com.xk.websocket.server;
import java.io.IOException;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/myws") //这个注解是把这个类变成了一个服务器端点
public class MyServer {
/**
* @onOpen 表示当有一个客户端和服务端连接成功时,回调这个函数
*/
@OnOpen
public void onOpen() {
System.out.println("有一个客户都安连接。。。");
}
/**
* @OnMessage 注解是当收到客户端发来的消息时,回调这个函数
* @param session - 收到的session会话,websocket会自动注入这个对象
* @param message - 收到的消息,websocket会自动注入这个对象
* @throws IOException
*/
@OnMessage
public void onMessage(Session session,String message) throws IOException {
System.out.println("客户端发来了一条消息:" + message);
//我服务端啥都不干,把消息给它返回去
session.getBasicRemote().sendText(message);
}
@OnClose
public void onClose(Session session) throws IOException {
if(session.isOpen()) {
session.close();
}
}
}
这里类上加了一个注解,@ServerEndpoint("/myws")表示把这个类变成一个服务器端点,也就是说tomcat服务器会把这个路径映射localhost:8080/myws,让客户端进行连接。
运行效果图:
下一章我们来讲解一下用WebSocket技术如何做聊天室: