websocket(一)–原生websocket使用
文章目录
一、简介
websocket可以在单tcp连接上进行全双工通信协议,即是服务端和客户端间可双向通信。这里对原生的websocket
使用进行示例介绍(需要新版浏览器支持)。
二、java端关键点
2.1 ServerEndpointExporter
ServerEndpointExporter,即org.springframework.web.socket.server.standard.ServerEndpointExporter,用于检测和注册以@ServerEndpoint注解的websocket endpoints。
2.2 Session
Session,即javax.websocket.Session,会话类,记录会话相关信息。
2.3 @ServerEndpoint
注解在类上,配置websocket endpoints,设置websocket连接地址。
2.4 处理方法
在endpoints类中,使用注解在方法,对连接过程进行处理。
- @OnOpen:websocket连接时处理器;
- @OnMessage:消息处理;
- @OnError:连接出错处理;
- @OnClose:连接失败处理;
三、前端关键点
3.1 websocket地址
以ws或wss开头,如:
var url = "ws://localhost:8080/talk_websocket/"
3.2 创建连接
使用WebSocket对象创建连接,如:
var webSocket = new WebSocket(url);
3.3 处理方法
- webSocket.onopen:连接建立;
- webSocket.onmessage:接收消息;
- webSocket.onerror: 连接出错;
- webSocket.onclose: 关闭连接;
四、 使用示例
这里使用spring boot,以聊天室为例进行示例。
4.1 添加maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
4.2 生成spring boot 启动类
package com.dragon.websocket_study;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class WebsocketStudyApplication {
public static void main(String[] args) {
SpringApplication.run(WebsocketStudyApplication.class, args);
}
}
4.3 定义spring web mvc配置类
package com.dragon.websocket_study.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
/
* 检测和注册endpoints
* @return
*/
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
/
* 添加静态文件
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/").addResourceLocations("classpath:/static/");
}
}
4.4 配置endpoint类及相关处理方法
package com.dragon.websocket_study.websocket;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ServerEndpoint("/talk_websocket/{uid}") //websocket连接地址
@Component
public class TalkWebSocketEndpoint {
//记录会话
private static ConcurrentHashMap<String, Session> sessionMap = new ConcurrentHashMap<>();
/
* 连接时处理类
* @param uid
* @param session
* @throws IOException
*/
@OnOpen
public void onOpen(@PathParam("uid") String uid, Session session) throws IOException {
sessionMap.put(uid, session);
session.getBasicRemote().sendText("welcome to talk");
}
/
* 接收消息处理类
* @param uid
* @param message
* @param session
* @throws IOException
*/
@OnMessage
public void onMessage(@PathParam("uid") String uid, String message, Session session) throws IOException {
for (Map.Entry<String, Session> entry : sessionMap.entrySet()) {
entry.getValue().getBasicRemote().sendText(message);
}
}
/
* 出错处理器
* @param uid
* @param e
*/
@OnError
public void onError(@PathParam("uid") String uid, Throwable e) {
sessionMap.remove(uid);
}
/
* 连接失败处理器
* @param uid
* @param session
* @param reason
*/
@OnClose
public void onClose(@PathParam("uid") String uid, Session session, CloseReason reason) {
sessionMap.remove(uid);
}
}
4.5 配置页面controller类
package com.dragon.websocket_study.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("rawWebSocket")
public class RawWebSocketController {
@RequestMapping("talk/{uid}")
public String talkWebsocket(Model model, @PathVariable String uid) {
model.addAttribute("uid", uid);
return "talk_websocket";
}
}
4.6 前端添加jquery
请自行下载jquery-3.1.1.min.js
4.7 thymeleaf页面代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#historyId {
border: 1px black solid;
height: 370px;
width: 500px;
overflow-y: scroll;
word-break: break-all;
}
#msgId {
width: 500px;
height: 130px;
}
#talkId {
/*text-align: center;*/
}
</style>
</head>
<body>
<section id="talkId">
<header>
tip:<span id="tipId" th:text="${uid}"></span>
</header>
<article id="historyId">
</article>
<article>
<textarea id="msgId"></textarea>
</article>
<footer>
<button id="sendId">send</button>
<button id="closeId">close</button>
<button id="clearId">clear</button>
<button id="connectId">connect</button>
</footer>
</section>
<script th:src="@{/static/js/jquery-3.1.1.min.js}"></script>
<script th:inline="javascript">
$(function () {
if('WebSocket' in window){
console.log("support websocket");
}else{
console.log("not support websocket");
}
var webSocket;
var initWebSocket = function (uid) {
var url = "ws://" + window.location.host + "/talk_websocket/" + [[${uid}]];
webSocket = new WebSocket(url);
//连接建立
webSocket.onopen = function (event) {
$("#tipId").html("connect success");
};
//接收消息
webSocket.onmessage = function (event) {
$("#historyId").append("<p>" + event.data + "</p>");
$("#historyId").scrollTop($("#historyId")[0].scrollHeight);
};
//连接出错
webSocket.onerror = function (e) {
$("#tipId").html("connect error");
};
//关闭连接
webSocket.onclose = function (e) {
$("#tipId").html("connect close");
};
};
var sendMsg = function () {
var msg = $("#msgId").val();
console.log("send msg : " + msg);
webSocket.send(msg);
$("#msgId").val("")
};
//点按钮发送消息
$("#sendId").click(function () {
sendMsg();
});
//回车发消息
$(document).keyup(function (e) {
if (e.keyCode == 13) {
sendMsg();
}
});
//清空记录
$("#clearId").click(function () {
$("#historyId").empty();
});
//连接
$("#connectId").click(function () {
initWebSocket($("#uid").val())
});
//关闭连接
$("#closeId").click(function () {
webSocket.close();
});
$("#historyId").scrollTop($("#historyId")[0].scrollHeight);
})
</script>
</body>
</html>
至此,使用websocket开发的简单聊天室完成。
运行WebsocketStudyApplication类,访问http://localhost:8080/rawWebSocket/talk/1地址即可。