1.引入pom文件
<!--web socket--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0</version> <scope>provided</scope> </dependency> <!--springBoot thymeleaf模板--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> <version>1.5.1.RELEASE</version> </dependency>
2.集成WebSocket
/**
* @author tracyclock
* @date 2018/10/18
* 首先要注入ServerEndpointExporter,这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint。
* 如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理
*/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
@Slf4j
@ServerEndpoint(value = "/webSocket" )
@Component
public class TracyWebSocket {
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
/**
* 连接建立成功调用的方法
* 1.可通过@ServerEndpoint(value = "/webSocket/{key}" ) @PathParam("key") 传入必传值
* 2.webSocket = new WebSocket("ws://localhost:9999/webSocket?key"); session.getQueryString() = key
* key可以传入当期用户的唯一标识
*/
@OnOpen
public void onOpen(Session session) throws Exception{
log.info("onOpen() queryString:{}",session.getQueryString());
this.session = session;
WebSocketMapUtil.put(session.getQueryString(),this);
try {
sendMessage("true" );
} catch (IOException e) {
log.info("onOpen() error:{}",e);
}
}
/**
* 连接关闭调用的方法
* @throws Exception
*/
@OnClose
public void onClose() throws Exception{
log.info("onClose()!!!");
WebSocketMapUtil.remove(session.getQueryString());
}
/**
* 收到客户端消息后调用的方法
* @param message 客户端发送过来的消息
* @param session 可选的参数
* @throws IOException
*/
@OnMessage
public void onMessage(String message, Session session) throws IOException {
log.info("onMessage!!!!!");
/*try {
TracyWebSocket myWebSocket= ((TracyWebSocket) WebSocketMapUtil.get(session.getQueryString().replace("service", "client")));
if(myWebSocket != null){
myWebSocket.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
}*/
System.out.println("来自客户端的消息:" + message);
//群发消息
/*for (TracyWebSocket item : webSocketSet) {
try {
item.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
}*/
}
/**
* 发生错误时调用
*/
@OnError
public void onError(Session session, Throwable error){
log.info("onError() error:{}",error);
}
/**
* 发送消息方法
*/
public void sendMessage(String message) throws IOException {
log.info("sendMessage() message:{}",message);
//this.session.getAsyncRemote().sendText(message);
try {
this.session.getBasicRemote().sendText(message);
} catch (Exception e) {
log.info("sendMessage() error:{}",e);
}
}
/**
* 群发消息方法
*/
public void sendInfoAll(String message) throws IOException{
log.info("sendInfoAll() start!");
for(TracyWebSocket tracyWebSocket : WebSocketMapUtil.getValues()){
tracyWebSocket.sendMessage(message);
}
}
/**
* 点对点,给客户端单发消息
*/
public void sendInfoSingle(WsMessage wsMessage) throws IOException {
log.info("sendInfoSingle() key:{} message:{}",wsMessage.getId(),wsMessage.getMessage());
if(StringUtils.isNotBlank(wsMessage.getId())){
TracyWebSocket tracyWebSocket = WebSocketMapUtil.get(wsMessage.getId());
if(tracyWebSocket != null){
try {
tracyWebSocket.sendMessage(wsMessage.getMessage().toString());
} catch (IOException e) {
log.info("sendInfoSingle() error:{}",wsMessage.getId(),wsMessage.getMessage());
}
}
}
}
/**
* 对符合条件的客户端发送消息
*/
public void sendInfoSet(Set<String> keySet, String message) throws IOException {
log.info("sendInfoSet() key:{} message:{}",keySet,message);
if(!CollectionUtils.isEmpty(keySet)){
keySet.forEach(key -> {
TracyWebSocket tracyWebSocket = WebSocketMapUtil.get(key);
if(tracyWebSocket != null){
try {
tracyWebSocket.sendMessage(message);
} catch (IOException e) {
log.info("sendInfoSet() error:{}",e);
}
}
});
}
}
}
/**
* @author tracyclock
* 2018/09/04
* 记录链接成功的用户
*/
public class WebSocketMapUtil {
public static ConcurrentMap<String, TracyWebSocket> webSocketMap = new ConcurrentHashMap<>();
public static void put(String key, TracyWebSocket tracyWebSocket){
webSocketMap.put(key, tracyWebSocket);
}
public static TracyWebSocket get(String key){
return webSocketMap.get(key);
}
public static void remove(String key){
webSocketMap.remove(key);
}
public static Collection<TracyWebSocket> getValues(){
return webSocketMap.values();
}
}
/**
* @author tracyclock
* @date 2018/10/18
* 自定义消息体
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class WsMessage<T> implements Serializable{
private static final long serialVersionUID = -3477023334141401126L;
private T message;
private String id;
}
3.编写html
webScoketA:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
Welcome<br/>
<input id="text" type="text" /><button onclick="send()">Send</button> <button onclick="closeWebSocket()">Close</button>
<div id="message">
</div>
</body>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript">
var websocket = null;
//判断当前浏览器是否支持WebSocket
if('WebSocket' in window){
websocket = new WebSocket("ws://127.0.0.1:5678/webSocket?a");
}
else{
alert('Not support webSocket')
}
//连接发生错误的回调方法
websocket.onerror = function(){
setMessageInnerHTML("error");
};
//连接成功建立的回调方法
websocket.onopen = function(event){
setMessageInnerHTML("webSocket open");
}
//接收到消息的回调方法
websocket.onmessage = function(event){
setMessageInnerHTML(event.data);
}
//连接关闭的回调方法
websocket.onclose = function(){
setMessageInnerHTML("webSocket close");
}
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function(){
websocket.close();
}
//将消息显示在网页上
function setMessageInnerHTML(innerHTML){
document.getElementById('message').innerHTML += "---------------"+innerHTML + '<br/>';
}
//关闭连接
function closeWebSocket(){
websocket.close();
}
//发送消息
function send(){
var message = document.getElementById('text').value;
$.ajax({
type: "POST",
dataType: 'json',
contentType: 'application/json;charset=utf-8',
url: "http://127.0.0.1:5678/webSocket/send",
data: JSON.stringify({
"message": message.toString(),
"id": "b"
}),
success: function (data){
}
})
//websocket.send(message);
document.getElementById('message').innerHTML += message + "-------------" + '<br/>';
}
</script>
</html>
webScoketB:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Title</title>
</head>
<body>
Welcome<br/>
<input id="text" type="text" /><button onclick="send()">Send</button> <button onclick="closeWebSocket()">Close</button>
<div id="message">
</div>
</body>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript">
var websocket = null;
//判断当前浏览器是否支持WebSocket
if('WebSocket' in window){
websocket = new WebSocket("ws://127.0.0.1:5678/webSocket?b");
}
else{
alert('Not support websocket')
}
//连接发生错误的回调方法
websocket.onerror = function(){
setMessageInnerHTML("error");
};
//连接成功建立的回调方法
websocket.onopen = function(event){
setMessageInnerHTML("open");
}
//接收到消息的回调方法
websocket.onmessage = function(event){
setMessageInnerHTML(event.data);
}
//连接关闭的回调方法
websocket.onclose = function(){
setMessageInnerHTML("close");
}
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function(){
websocket.close();
}
//将消息显示在网页上
function setMessageInnerHTML(innerHTML){
document.getElementById('message').innerHTML += "---------------"+innerHTML + '<br/>';
}
//关闭连接
function closeWebSocket(){
websocket.close();
}
//发送消息
function send(){
var message = document.getElementById('text').value;
$.ajax({
type: "POST",
dataType: 'json',
contentType: 'application/json;charset=utf-8',
url: "http://127.0.0.1:5678/webSocket/send",
data: JSON.stringify({
"message": message.toString(),
"id": "a"
}),
success: function (data){
}
})
//websocket.send(message);
document.getElementById('message').innerHTML += message + "-------------" + '<br/>';
}
</script>
</html>
4.编写controller
@Slf4j
@Controller
@RequestMapping("/webSocket")
public class WebSocketController {
@Autowired
private TracyWebSocket tracyWebSocket;
@RequestMapping(value = "/send",method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public void send(@RequestBody WsMessage wsMessage) {
log.info("send!!!!!!!!!!!!!!");
try {
tracyWebSocket.sendInfoSingle(wsMessage);
} catch (IOException e) {
e.printStackTrace();
}
}
@RequestMapping("/test")
public void test() {
log.info("test!!!!!!!!!!!!!!");
}
@RequestMapping("/webSocketA")
public String webSocketA() {
log.info("go webSocketA");
return "webSocketA";
}
@RequestMapping("/webSocketB")
public String webSocketB() {
log.info("go webSocketB");
return "webSocketB";
}
}
5.结果展示
6.简单的webSocket就成功了