@サーバーエンドポイント:
主に現在のクラスを WebSocket サーバーとして定義し、アノテーションの値はユーザー接続の端末アクセス URL アドレスを監視するために使用され、クライアントはこの URL を通じて WebSocket サーバーに接続できます。
説明: このプロジェクトは springboot に統合された Websocket です。
私のプロジェクトは依存関係をインポートするために Gradel を使用しています。Maven の依存関係は以下に添付されています。バージョンは springboot と一致しています。
build.gradle
compile group: 'org.springframework.boot', name: 'spring-boot-starter-websocket', version: '2.0.4.RELEASE'
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
この記事ではアノテーション プログラミングを採用しており、迅速な開発は次のとおりです:
コア プロセッサ MyWebSocketServer.java
@ServerEndpoint(value = "/mysocket", encoders = AnswerEncoder.class)
@Component
@Slf4j
public class MyWebSocketServer {
/**
* 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
*/
private static int onlineCount = 0;
/**
* concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
*/
private static final CopyOnWriteArraySet<ScreenWebSocketServer> WEB_SOCKET_SET = new CopyOnWriteArraySet<ScreenWebSocketServer>();
/**
* 与某个客户端的连接会话,需要通过它来给客户端发送数据。
*/
private Session session;
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session) {
this.session = session;
// 将当前连接加入到set中
WEB_SOCKET_SET.add(this);
// 连接数+1
addOnlineCount();
log.info("MyWebSocketServer 加入新的连接,当前连接数为" + getOnlineCount());
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
// 将当前连接从set中移除
WEB_SOCKET_SET.remove(this);
// 连接数-1
subOnlineCount();
log.info("MyWebSocketServer 有一连接关闭!当前连接数为" + getOnlineCount());
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("MyWebSocketServer 收到来自窗口" + session.getId() + "的信息:" + message);
}
/**
* @param session 连接session
* @param error 措施信息
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("MyWebSocketServer 连接发生错误");
error.printStackTrace();
}
/**
* <p>@Description:給session连接推送消息</p>
* <p>@param [message]</p>
* <p>@return void</p>
* <p>@throws </p>
*/
private void sendMessage(Object message) throws IOException {
try {
this.session.getBasicRemote().sendObject(message);
} catch (EncodeException e) {
e.printStackTrace();
log.error("MyWebSocketServer 向客户端推送数据发生错误");
}
}
/**
* <p>@Description:向所有连接群发消息</p>
* <p>@param [message]</p>
* <p>@return void</p>
* <p>@throws </p>
*/
public static void sendMessageToAll(Object message){
for (ScreenWebSocketServer item : WEB_SOCKET_SET) {
try {
item.sendMessage(message);
} catch (IOException e) {
log.error("MyWebSocketServer 向客户端推送数据发生错误");
}
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
ScreenWebSocketServer.onlineCount++;
}
public static synchronized void subOnlineCount() {
ScreenWebSocketServer.onlineCount--;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ScreenWebSocketServer that = (ScreenWebSocketServer) o;
return Objects.equals(session, that.session);
}
@Override
public int hashCode() {
return Objects.hash(session);
}
}
メッセージを送信するエンコーダー AnswerEncoder.java
public class AnswerEncoder implements Encoder.Text<Answer> {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void init(EndpointConfig arg0) {
// TODO Auto-generated method stub
}
@Override
public String encode(Answer answer) throws EncodeException {
return JSONUtil.toJsonStr(answer);
}
}
最も重要なステップ: ServerEndpointExporter を Spring コンテナー管理に公開することで、 @ServerEndpoint アノテーションが付けられた WebSocket プロセッサーを挿入するのに役立ちます。そうしないと、上記の構成が有効になりません。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* File Name: WebsocketConfiguration
* Description: Websocket 相关配置类
*/
@Configuration
public class WebSocketConfiguration {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
これまでのところ、WebSocket は構成されています。それでは、WebSocket を呼び出す方法と、サーバーからクライアントにメッセージをアクティブにプッシュする方法を教えてください。次のサンプルコードを参照してください。
@RequestMapping("socketPushTest")
@RestController
public class MyWebSocketPushTest {
@ApiOperation("给已连接的所有session进行群发")
@PostMapping("/sendMessageToAll")
public void push(@RequestBody Object data) {
// 给前端群发数据变更消息
Answer success = Answer.success("群发的消息-----啦啦啦");
MyWebSocketServer.sendMessageToAll(success);
}
}
コア コードは MyWebSocketServer.sendMessageToAll(success);
です。これで Springboot 埋め込み WebSocket が構成され、URL を通じてこのサービスに接続できるようになりました。
説明
: 私の springboot プロジェクトの起動ポート (つまり、yml ファイルの server.port) は 9090
ws://127.0.0.1:9090/mysocket
ステップ 1. ws request user をシミュレートします。 1
ws リクエストユーザーをシミュレートします 2
idea console の印刷ログを確認し
ます
質問と回答: 設定後、springboot プロジェクトがエラーを報告し始めます。このブログの使用範囲は springboot+tomcat です。起動時にエラーが報告される場合は、
maven または gradle の依存関係のときに
spring-boot-starter-tomcatを除外してください構成は以下の通りです。
build.gradle
compile("org.springframework.boot:spring-boot-starter-web:2.1.4.RELEASE") {
exclude module: "spring-boot-starter-tomcat"
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
</exclusion>
</exclusions>
</dependency>
プロジェクト公開サーバーが桟橋にある場合は、外に出て左に曲がってください。このブログは適用されません。このブログで書かれたコードは、独自の springboot と統合されている Tomcat を使用して WebSocket を公開するものであり、追加のポートは有効になっていません。!!!