hmp 4 роки тому
батько
коміт
3e7026cbb2

+ 30 - 0
pom.xml

@@ -249,6 +249,28 @@
             <artifactId>bcprov-jdk15to18</artifactId>
             <version>1.68</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+            <version>2.1.6.RELEASE</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <version>2.1.6.RELEASE</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-tomcat</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-undertow</artifactId>
+        </dependency>
     </dependencies>
 
     <build>
@@ -309,6 +331,14 @@
                 </configuration>
             </plugin>
 
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <testFailureIgnore>true</testFailureIgnore>
+                </configuration>
+            </plugin>
+
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-dependency-plugin</artifactId>

+ 16 - 0
src/main/java/org/springblade/common/config/WebSocketConfig.java

@@ -0,0 +1,16 @@
+package org.springblade.common.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+/**
+ * @author cy-computer
+ */
+@Configuration
+public class WebSocketConfig {
+	@Bean
+	public ServerEndpointExporter serverEndpointExporter() {
+		return new ServerEndpointExporter();
+	}
+}

+ 11 - 0
src/main/java/org/springblade/common/constant/SystemConstant.java

@@ -149,6 +149,17 @@ public interface SystemConstant {
 		}
 	}
 
+	@Getter
+	enum ChatType{
+		GROUP_CHAT("群聊", 1),
+		PRIVATE_CHAT("私聊", 0);
 
+		String name;
+		Integer value;
+		ChatType(String name, Integer value){
+			this.name = name;
+			this.value = value;
+		}
+	}
 
 }

+ 31 - 0
src/main/java/org/springblade/modules/webSocket/WebSocketController.java

@@ -0,0 +1,31 @@
+package org.springblade.modules.webSocket;
+
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.Api;
+import lombok.AllArgsConstructor;
+import org.springblade.core.tool.api.R;
+import org.springblade.modules.webSocket.dto.Message;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * @author cy-computer
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("cyzh-ldt/webSocket")
+public class WebSocketController {
+	@Resource
+	private WebSocketServer webSocketServer;
+
+	@PostMapping("sendInfo")
+	public R sendInfo(@RequestBody Message message){
+		webSocketServer.sendInfo(message.getSid(),JSON.toJSONString(message,true));
+		return R.success("发送成功");
+	}
+}

+ 154 - 0
src/main/java/org/springblade/modules/webSocket/WebSocketServer.java

@@ -0,0 +1,154 @@
+package org.springblade.modules.webSocket;
+
+import cn.hutool.log.Log;
+import cn.hutool.log.LogFactory;
+import com.alibaba.fastjson.JSON;
+import org.springblade.common.constant.SystemConstant;
+import org.springblade.core.tool.api.R;
+import org.springblade.modules.webSocket.dto.Message;
+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.Date;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @author cy-computer
+ */
+@ServerEndpoint("/websocket/{sid}")
+@Component
+public class WebSocketServer {
+
+	/**
+	 * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
+	 */
+	private static AtomicInteger onlineNum = new AtomicInteger();
+	/**
+	 * concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
+	 */
+	private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();
+
+
+	/**
+	 * 给指定用户发送消息
+	 * @param sid
+	 * @param message
+	 */
+	public void sendInfo(String sid, String message){
+		Session session = sessionPools.get(sid);
+		try {
+			sendMessage(session, message);
+		}catch (Exception e){
+			e.printStackTrace();
+		}
+	}
+
+
+	/**
+	 * 群发消息
+	 * @param message
+	 */
+	public void broadcast(String message){
+		for (Session session: sessionPools.values()) {
+			try {
+				sendMessage(session, message);
+			} catch(Exception e){
+				e.printStackTrace();
+				continue;
+			}
+		}
+	}
+
+	/**
+	 * 发送消息
+	 * @param session
+	 * @param message
+	 * @throws IOException
+	 */
+	private void sendMessage(Session session, String message) throws IOException {
+		if(session != null){
+			synchronized (session) {
+				System.out.println("发送数据:" + message);
+				session.getBasicRemote().sendText(message);
+			}
+		}
+	}
+	/**
+	 * 成功建立连接的回调
+	 * @param session
+	 * @param sid
+	 */
+	@OnOpen
+	public void onOpen(Session session, @PathParam(value = "sid") String sid){
+		sessionPools.put(sid, session);
+		addOnlineCount();
+		System.out.println(sid + "加入webSocket!当前连接数为" + onlineNum);
+		//给客户端返回连接成功的消息
+		Message message = new Message();
+		message.setSid(sid);
+		message.setContent("连接成功");
+		message.setType(SystemConstant.ChatType.PRIVATE_CHAT);
+		this.sendInfo(sid,JSON.toJSONString(message,true));
+	}
+
+	/**
+	 * 断开连接的回调
+	 * @param sid
+	 */
+	@OnClose
+	public void onClose(@PathParam(value = "sid") String sid){
+		sessionPools.remove(sid);
+		subOnlineCount();
+		System.out.println(sid + "断开webSocket连接!当前连接数为" + onlineNum);
+	}
+
+
+	/**
+	 * 客户端给服务端发送信息的回调
+	 * @param message
+	 * @throws IOException
+	 */
+	@OnMessage
+	public void onMessage(String message) throws IOException{
+		System.out.println("server get" + message);
+		Message msg=JSON.parseObject(message, Message.class);
+		msg.setDate(new Date());
+		if (SystemConstant.ChatType.GROUP_CHAT.equals(msg.getType())) {
+			//群发消息
+			broadcast(JSON.toJSONString(msg,true));
+		} else {
+			sendInfo(msg.getSid(), JSON.toJSONString(msg,true));
+		}
+	}
+
+	/**
+	 * 错误时的回调
+	 * @param session
+	 * @param throwable
+	 */
+	@OnError
+	public void onError(Session session, Throwable throwable){
+		System.out.println("发生错误");
+		throwable.printStackTrace();
+	}
+
+
+	/**
+	 * 增加连接人数
+	 */
+	public static void addOnlineCount(){
+		onlineNum.incrementAndGet();
+	}
+
+	/**
+	 * 减少连接人数
+	 */
+	public static void subOnlineCount() {
+		onlineNum.decrementAndGet();
+	}
+}

+ 30 - 0
src/main/java/org/springblade/modules/webSocket/dto/Message.java

@@ -0,0 +1,30 @@
+package org.springblade.modules.webSocket.dto;
+
+import lombok.Data;
+import org.springblade.common.constant.SystemConstant;
+
+import java.util.Date;
+
+/**
+ * @author cy-computer
+ */
+@Data
+public class Message {
+
+	/**
+	 * 用户id
+	 */
+	private String sid;
+	/**
+	 * 消息内容
+	 */
+	private String content;
+	/**
+	 * 消息类型,群发私发
+	 */
+	private SystemConstant.ChatType type;
+	/**
+	 * 发送日期
+	 */
+	private Date date;
+}