HTML5 WebSocket
WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。
浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。
当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。
WebSocket 实例
WebSocket 协议本质上是一个基于 TCP 的协议。
为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息"Upgrade: WebSocket"表明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。
以上来自 菜鸟编程
实现一个webSocket应用程序,我们要学会几个基本操作。
1. 开启连接
2. 客户端给服务器端发送数据
3. 服务器端接收数据
4. 服务器端给客户端发送数据
5. 客户端接收数据
6. 监听三类基本事件: onopen, onmessage,onclose
onmessage 是发送数据时的响应事件。
onopen是打开连接时的响应事件。
onclose是关闭连接时的响应事件。
简单实现
新建一个web项目,并复制tomcat下jar,tomcat-websocket.jar和websocket-api.jar,新建webSocket配置类
package webSocket;
import java.util.Set;
import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;
/**
* websockket 核心配置类,项目启动时会自动启动,类似与ContextListener.
*/
public class WebSocketConfig implements ServerApplicationConfig{
/**
* 注解方式
* 扫描src下所有类@ServerEndPoint注解的类。
*/
@Override
public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> arg0) {
System.out.println("============="+arg0.size());
//返回
return arg0;
}
/**
* 获取所有以接口方式配置的webSocket类。
*/
@Override
public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> arg0) {
return null;
}
}
新建服务端程序类
package socket;
import java.io.IOException;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
/**
* : EndPoint 就指的是 一个webSocket的一个服务端程序
* @author jun
*
*/
@ServerEndpoint("/echo")
public class EchoSocket {
@OnOpen
public void openSock(Session session){
System.out.println("链接打开了"+session.getId());
}
@OnMessage
public void onMesssage(String msg,Session session){
System.out.println("客户端说->"+msg);
try {
session.getBasicRemote().sendText("服务器说:你也好");
} catch (IOException e) {
e.printStackTrace();
}
}
@OnClose
public void closeSocket(Session session){
System.out.println("链接关闭了"+session.getId());
}
}
新建index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<script type="text/javascript">
function ws_init(){
var target="ws://localhost:8080/MyAcitivity/echo";/* 对应你的服务端程序地址 */
if ('WebSocket' in window) {
ws = new WebSocket(target);
} else if ('MozWebSocket' in window) {
ws = new MozWebSocket(target);
} else {
alert('WebSocket is not supported by this browser.');
return;
}
ws.onopen=function(){
console.info("webSocket通道建立成功!!!");
};
ws.onmessage =function (event){
var div=document.getElementById("getServer");
div.innerHTML+=event.data;
}
}
function ws_send(){
var msg = document.getElementById("msg");
ws.send(msg.value);
msg.value="";
}
</script>
</head>
<body>
<button onclick="ws_init();" >建立连接</button>
<hr/>
<input id="msg" />
<button onclick="ws_send();">send</button>
<div id="getServer"> </div>
</body>
</html>
这样一个最简单的demo实现,是webSocket实现的基础
使用webSocket实现简易聊天室
群聊:群聊的重点在于广播,每次建立链接的时候,我把当前新进入的用户session存入全局变量sessionSet,
当任一用户发送消息后,后台的服务端程序接收到信息,遍历sessionSet进行发送消息到前端用户
源码地址:demo
单聊:单聊的话实现可以在定义一个用户名或者id对应session的map,前端控制私聊给谁,发送消息的时候携带要发送给用户的id或唯一标识,后台进行根据这个标识去找目前已建立连接的session,然后直接发送就可以了
注:客户端手动刷新的时候,或者直接退出的时候或者出现其他错误,后台会抛出异常这时可以使用@OnError来进行处理
/**
* 错误时调用
* @param session
* @param error
*2018年6月3日
*/
@OnError
public void error(Session session, Throwable error){
System.out.println(session.getId());
}
当用户在前端关闭页面或刷新的时候,也可以进行事件监听来进行前端主动关闭链接
window.onbeforeunload = function () {
ws.close();
}