1. 介绍
webSocket是HTML5新增的协议,是一个持久化的协议。它的目的是在浏览器和服务器之间建立一个不受限的双向通信通道。例如:服务器可以在任意时刻向浏览器发送消息。
webSocket的出现,让浏览器和服务器之间可以建立无限制的全双工通信,任何一方都可以主动发消息给对方。wesocket并不是全新的协议,而是利用HTTP协议来建立连接的。
- WebSocket通过HTTP端口80和443进行工作,并支持HTTP代理和中介,从而使其与HTTP协议兼容。
- 为了实现兼容性,WebSocket握手使用HTTP Upgrade头从HTTP协议更改为WebSocket协议。
- Websocket使用ws或wss的统一资源标志符(URI),分别对应明文和加密连接。
2. 实现方式
1)编程式:继承类javax.websocket.Endpoint并实现其方法
2)注解式:定义一个类,在类上添加@ServerEndpoint注解,表明该类是一个webSocket类。
@ServerEndpoint可以注解到任何类上,但是想实现服务端的完整功能,还需要配合几个生命周期的注解使用,这些生命周期注解只能注解在方法上:
@OnOpen 建立连接时触发。
@OnClose 关闭连接时触发。
@OnError 发生异常时触发。
@OnMessage 接收到消息时触发。
3. 注解方式实现聊天的事例
1. 引用maven
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
2. 服务器端代码实现
@ServerEndpoint(value = "/myWebSocket/{userId}")
public class MyWebSocket{
private static Map<String, MyWebSocket> map = new HashMap<>();
private Session session;
private String userId;
@OnOpen
public void onOpen(Session session, @PathParam(value="userId") String userId) {
this.session = session;
this.userId = userId;
map.put(userId, this);
System.out.println(userId+"登录了");
}
@OnClose
public void onClose(){
System.out.println("onclose");
map.remove(userId);
}
@OnError
public void onError(Throwable t) throws IOException {
System.out.println("onerror");
this.session.close(new CloseReason(CloseReason.CloseCodes.CLOSED_ABNORMALLY, "系统异常"));
}
@OnMessage
public void onMessage(String message, Session session){
System.out.println("收到:"+message);
for (String s : map.keySet()) {
map.get(s).sendMessage(message);
}
}
public void sendMessage(String message){
try {
this.session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. 客户端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>
<div>
姓名:<input type="text" id="userName" />
<button id="connect" onclick="connectSocket()">连接</button>
<button id="close" onclick="closeSocket()">断开</button>
</div>
<div>
内容:<input type="text" id="chat" />
<button id="send" onclick="sendMessage()">发送</button>
</div>
</p>
<div id="console-container">
<div id="console"/>
</div>
<script type="application/javascript">
let socket = null;
function connectSocket(){
var a = document.getElementById("userName").value
connect("ws://localhost:8080/myWebSocket/"+a)
}
function closeSocket(){
if(socket != null){
socket.close()
socket = null
}
}
function sendMessage(){
var name = document.getElementById("userName").value
var message = document.getElementById("chat").value
if(socket != null){
socket.send(name+"说:"+message)
document.getElementById("chat").value='';
}
}
function connect(host){
if ('WebSocket' in window) {
socket = new WebSocket(host);
} else if ('MozWebSocket' in window) {
socket = new MozWebSocket(host);
} else {
console.log('Error: WebSocket is not supported by this browser.');
return;
}
socket.onopen= function (){
console.log("Info: websocket connection opend.")
}
socket.onclose=function(){
console.log("Info:websocket connection closed.")
}
socket.onmessage = function(message){
var console = document.getElementById('console');
var p = document.createElement('p');
p.innerHTML = message.data;
console.appendChild(p);
while (console.childNodes.length > 25) {
console.removeChild(console.firstChild);
}
console.scrollTop = console.scrollHeight;
}
}
</script>
</body>
</html>
4. 打开两个页面,分别以小王和小李身份建立连接,然后发送内容,就可以互相聊天了。