1 基本步骤
1. 开启连接
2. 客户端给服务器端发送数据
3. 服务器端接收数据
4. 服务器端给客户端发送数据
5. 客户端接收数据
6. 监听三类基本事件: onopen, onmessage,onclose
提示: onmessage 是发送数据时的响应事件。
onopen是打开连接时的响应事件。
onclose是关闭连接时的响应事件。
2 Demo
使用webSocket实现一个单机的 echo练习。
目的是: 熟悉webSocket 客户端和服务器端的API。
2.1 WebSocketConfig
2.1.1 参考tomcat
F:\Tomcat\apache-tomcat-7.0.65\webapps\examples\WEB-INF\classes\websocket
2.1.2 demo
package com.bjsxt.config;
import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;
import java.util.Set;
public class WebSocketConfig implements ServerApplicationConfig {
/*
* 上面的两个方法都是用来注册 webSocket的。 只不过注册的方式不同。
* 1. getAnnotatedEndpointClasses 1方法是注解的方式
* 2. getEndpointConfigs 2方法是 接口的方式
* 显然 注解的方式更加的 灵活简单。 接口的方式更加的传统,严谨。
*/
@Override
public Set<ServerEndpointConfig>getEndpointConfigs(Set<Class<? extends Endpoint>> set) {
return null;
}
@Override
public Set<Class<?>>getAnnotatedEndpointClasses(Set<Class<?>> arg0) {
System.out.println("正在扫描所有的webSocket服务!!!" + arg0.size());
return arg0;
}
}
2.1.3 启动tomcat
启动tomcat,输出..,再次验证ServerApplicationConfig启动tomcat之前就开始执行
2.2 EchoSocket
2.2.1 参考tomcat
第一步
F:\Tomcat\apache-tomcat-7.0.65\webapps\examples\WEB-INF\classes\websocket\echo
第四步
2.2.2 第一步创建一个 socket服务
2.2.3 第二步@OnOpen(在index.jsp第二步后)
前端使用发送了服务后,会自动调用此方法
启动tomcat点击按钮:
2.2.4 第三步@OnClose
关闭连接时,触发
2.2.5 第四步@OnMessage(在index.jsp第二步之后)
2.2.6 完整Demo
package com.bjsxt.socket; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import java.io.IOException; /** * Created by lan_jiaxing on 2018/2/1 0001. */ @ServerEndpoint("/echo") public class EchoSocket { public EchoSocket() { System.out.println("EchoSocket.EchoSocket()"); } @OnOpen public void open(Session session){ //一个session代表一次回话 System.out.println("sessionId:" + session.getId()); } @OnClose public void close(Session session){ //一个session代表一次回话 System.out.println("session:" + session.getId() + "通道关闭"); } @OnMessage public void message(Session session , String msg){ System.out.println("客户端:" + msg); try { session.getBasicRemote().sendText("服务器说:收到了"); } catch (IOException e) { e.printStackTrace(); } } }
2.3 Index.jsp
2.3.1 参考tomcat
第一步:F:\Tomcat\apache-tomcat-7.0.65\webapps\examples\websocket
第二步
2.3.2 第一步 前端创建一个WebSocket
此方法会自动调用后台带@OnOpen的方法
2.3.3 第二步send()方法(在EchoScoket第三步之后)
2.3.4 第三步接受服务器端的(在EchoScoket第四步之后)
在subSend方法中添加
2.3.5 完整demo
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<button οnclick="subOpen()">按钮</button>
<input id = "msg" /><button οnclick="subSend()">send</button>
<div id="dv"></div>
<script>
var ws = null;//一个ws对象就是一个通讯对象
var target = "ws://localhost:8080/websocket-01/echo"
function subOpen() {
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.onmessage = function (event) {
var dv = document.getElementById("dv")
dv.innerHTML += event.data;
}
}
function subSend() {
var msg = document.getElementById("msg").value;
ws.send(msg);
document.getElementById("msg").value = '';
}
</script>
</body>
</html>
3 前端面向对象改造
3.1 Index.jsp
调用构造函数以及初始化函数
<%@page contentType="text/html;charset=UTF-8" language="java" %>
<%
String contextPath =request.getContextPath();
String basePath = request.getScheme() +"://" + request.getServerName()+ ":" + request.getServerPort()+ contextPath;
String webSocketPath = "ws://" + request.getServerName()+ ":" + request.getServerPort()+ contextPath;
%>
<html>
<head>
<title>$Title$</title>
<script>
var contextPath = '<%=contextPath %>';
varbashPath = '<%=basePath %>';
var webSocketPath = '<%=webSocketPath %>';
</script>
</head>
<body>
<%--<button οnclick="subOpen()">连接按钮</button>--%>
<input id = "msg" /><button id="send">send</button>
<div id="dv"></div>
<script type="text/javascript"src= '<%=contextPath %>/js/index.js'></script>
<script>
var index = new Index({webSocketPath : webSocketPath}).init();
</script>
</body>
</html>
1.2 Index.js
构造函数
var Index = function(param) {
this.ws = null;//一个ws对象就是一个通讯对象
this.target= param.webSocketPath + "/echo";//webSocket的路径,写成target,区分传统http的url
return this;
}
/**
* 初始化函数
* @returns {Index}
*/
Index.prototype.init = function() {
this.webSocketMsg();
this.attactEvent();
return this;
}
/**
* websocket的一些相关操作:连接,通信,关闭
* @returns {Index}
*/
Index.prototype.webSocketMsg = function() {
/* 判断浏览器兼容性,new成功后,1.找到@ServerEndpoint("/echo"),
2.创立了连接,并执行@OnOpen的方法 */
if ('WebSocket'in window) {
this.ws = new WebSocket(this.target);
} else if ('MozWebSocket' in window) {
this.ws = new MozWebSocket(this.target);
} else {
alert('WebSocket是不被浏览器支持。');
return;
}
//连接成功响应,在后台@OnOpen后执行(了解)
this.ws.onopen = function () {
// alert("open........")
}
//连接成功响应,在后台@OnClose后执行(了解)
this.ws.onclose = function () {
// alert("close........")
}
/* event.data就是后台 session.getBasicRemote().sendText("服务器说:收到了")之后响应
注意:不是针对@OnMessage响应,而是针对 那个方法响应 */
this.ws.onmessage = function (event) {
var dv = document.getElementById("dv")
dv.innerHTML += event.data;
}
return this;
}
/**
* 注册函数相关操作
* @returns {Index}
*/
Index.prototype.attactEvent = function() {
var that= this;
var send= document.getElementById("send");
send.onclick = function() {
var msg = document.getElementById("msg").value;
that.ws.send(msg);
document.getElementById("msg").value = '';
}
return this;
}