master
王兵 3 years ago
parent c0e0ad890e
commit f7f1a40d56

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>xyz.wbsite</groupId>
<artifactId>test-websocket</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test-websocket</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<repositories>
<!-- 将中央仓库地址指向阿里云聚合仓库,提高下载速度 -->
<repository>
<id>central</id>
<name>Central Repository</name>
<layout>default</layout>
<url>https://maven.aliyun.com/repository/public</url>
</repository>
</repositories>
<pluginRepositories>
<!-- 将插件的仓库指向阿里云聚合仓库解决低版本maven下载插件异常或提高下载速度 -->
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>https://maven.aliyun.com/repository/public</url>
<layout>default</layout>
</pluginRepository>
</pluginRepositories>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</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>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.6.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,15 @@
package xyz.wbsite;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class TestWebsocketApplication {
public static void main(String[] args) {
SpringApplication.run(TestWebsocketApplication.class, args);
}
}

@ -0,0 +1,14 @@
package xyz.wbsite.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}

@ -0,0 +1,20 @@
package xyz.wbsite.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class IndexController {
@RequestMapping("/")
public String text(ModelMap map, HttpServletRequest request, HttpServletResponse response) {
map.put("name","张三");
return "index";
}
}

@ -0,0 +1,115 @@
package xyz.wbsite.endpoint;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
@ServerEndpoint("/websocket/{userId}")
@Controller
public class WebSocketManager {
static Log log = LogFactory.getLog(WebSocketManager.class);
/**
* concurrent线SetMyWebSocket
*/
private static ConcurrentHashMap<String, Session> keySessionMap = new ConcurrentHashMap<>();
private static ConcurrentHashMap<Integer, String> hashKeyMap = new ConcurrentHashMap<>();
/**
*
*/
@OnOpen
public void onOpen(Session session, @PathParam("userId") String userId) {
// 移除并关闭旧会话
if (keySessionMap.containsKey(userId)) {
Session remove = keySessionMap.remove(userId);
hashKeyMap.remove(remove.hashCode());
try {
remove.close();
} catch (IOException e) {
e.printStackTrace();
}
}
keySessionMap.put(userId, session);
hashKeyMap.put(session.hashCode(), userId);
log.info("用户连接:" + userId + ",当前在线人数为:" + keySessionMap.size());
sendMessage(userId, "连接成功");
}
/**
*
*/
@OnClose
public void onClose(Session session) {
if (hashKeyMap.containsKey(session.hashCode())) {
String userId = hashKeyMap.remove(session.hashCode());
keySessionMap.remove(userId);
log.info("用户退出:" + userId);
}
}
/**
*
*
* @param message
*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("收到客户端消息:" + message);
}
/**
*
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
if (hashKeyMap.containsKey(session.hashCode())) {
String userId = hashKeyMap.remove(session.hashCode());
keySessionMap.remove(userId);
log.error("用户错误:" + userId + ",原因:" + error.getMessage());
}
}
/**
*
*/
public void sendMessage(String userId, String message) {
Session session = keySessionMap.get(userId);
if (session == null) {
return;
}
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
e.printStackTrace();
}
}
@Scheduled(fixedDelay = 3 * 1000)
public void sendTask() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sendMessage("1", simpleDateFormat.format(new Date()));
}
}

@ -0,0 +1,55 @@
package xyz.wbsite.test;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;
public class Test {
public static void main(String[] args) {
final WebSocket[] socket = new WebSocket[1];
OkHttpClient mOkHttpClient = new OkHttpClient.Builder()
.retryOnConnectionFailure(true)
.build();
Request mRequest = new Request.Builder()
.url("ws://127.0.0.1:8080/websocket/1")
.build();
mOkHttpClient.newWebSocket(mRequest, new WebSocketListener() {
@Override
public void onOpen(WebSocket webSocket, Response response) {
socket[0] = webSocket;
System.out.println("连接已打开");
}
@Override
public void onMessage(WebSocket webSocket, String text) {
System.out.println("接收消息:" + text);
socket[0].send("收到消息");
}
@Override
public void onMessage(WebSocket webSocket, ByteString bytes) {
super.onMessage(webSocket, bytes);
}
@Override
public void onClosing(WebSocket webSocket, int code, String reason) {
System.out.println("连接关闭");
}
@Override
public void onClosed(WebSocket webSocket, int code, String reason) {
System.out.println("连接关闭");
}
@Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
System.out.println("连接失败");
}
});
}
}

@ -0,0 +1,24 @@
package xyz.wbsite.utils;
public class StringUtils {
public static boolean isNull(String str) {
return str == null;
}
public static boolean isNotNull(String str) {
return !isNull(str);
}
public static boolean isBlank(String str) {
return str != null && "".equals(str);
}
public static boolean isNotBlank(String str) {
return !isBlank(str);
}
}

@ -0,0 +1,18 @@
spring.freemarker.suffix=.ftl
spring.freemarker.enabled=true
spring.freemarker.allow-request-override=false
spring.freemarker.cache=true
spring.freemarker.check-template-location=true
spring.freemarker.charset=UTF-8
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=false
spring.freemarker.expose-session-attributes=false
spring.freemarker.expose-spring-macro-helpers=false
spring.freemarker.settings.template_update_delay=1
spring.freemarker.settings.locale=zh_CN
spring.freemarker.settings.datetime_format=yyyy-MM-dd HH:mm:ss
spring.freemarker.settings.date_format=yyyy-MM-dd
spring.freemarker.settings.number_format=#.##
spring.freemarker.settings.classic_compatible=true
spring.freemarker.settings.whitespace_stripping=true
spring.freemarker.settings.url_escaping_charset=utf-8

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<button onclick="javascript:WebSocketTest()">连接WebSocket</button>
<div id="info"></div>
<script type="text/javascript">
function log(msg) {
var li = document.createElement("li");
li.innerText = msg;
document.body.querySelector("#info").appendChild(li);
}
function WebSocketTest() {
if ("WebSocket" in window) {
// 打开一个 web socket
var ws = new WebSocket("ws://localhost:8080/websocket/1");
ws.onopen = function () {
// Web Socket 已连接上,使用 send() 方法发送数据
ws.send("发送数据");
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
log(received_msg)
};
ws.onclose = function () {
// 关闭 websocket
log("连接已关闭...");
};
} else {
// 浏览器不支持 WebSocket
log("您的浏览器不支持 WebSocket!");
}
}
</script>
</body>
</html>
Loading…
Cancel
Save

Powered by TurnKey Linux.