【メモ】WebSocket使ってみた

## はじめに
Websocket使って双方向通信ができるように実装してみました。
フロントは素のjavascriptでバックはjavaです。

### javascript

```javascript:test.js
var connection = new WebSocket('ws://localhost:8080/test');

connection.onopen = function(e) { 
    connection.send('test');
};

connection.onerror = function(error) { };
 

connection.onmessage = function(e) { 
    console.log('メッセージを受け取った');
    console.log(e.data);
    
};
  
connection.onclose = function() { };
```

### java

```java:WebSocketConfig.java
package com.example.demo.webSocket;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
/**
 * WebSocketの管理
 */
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
  /**
   * WebSocketの登録
   */
  @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(messageHandler(), "/test").setAllowedOrigins("*");
    }
  /**
   * WebSocketHandler（コントロールするクラス）を定義
   * @return WebSocketHandler
   */
    @Bean
    public WebSocketHandler messageHandler() {
        return new MessageHandler();
    }
}
```

```java:
package com.example.demo.webSocket;

import java.io.IOException;
import java.util.ArrayList;

import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
/**
 * WebSocketのHandler
 */
public class MessageHandler extends TextWebSocketHandler {

	private ArrayList< WebSocketSession > users;
    public MessageHandler(){
        users = new ArrayList<>();
    }
    /**
     * 接続確立
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        System.out.println("WebSocketの接続が確立しました。");
        if(users.stream()
                .noneMatch(user -> user.getId().equals(session.getId()))){
            users.add(session);
            System.out.println(session.getId());
        }
    }
    /**
     * メッセージの送受信
     */
    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {
        System.out.println("メッセージ受信:" + message.getPayload());
        try {
            TextMessage outputMessage = new TextMessage(message.getPayload());


            for(WebSocketSession onesession :users) {
            	System.out.println(onesession.getId());
            	onesession.sendMessage(outputMessage);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 接続終了
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        System.out.println("WebSocketの接続が終了しました。");
        users.stream()
        .filter(user -> user.getId().equals(session.getId()))
        .findFirst()
        .ifPresent(user -> users.remove(user));
    }
}
```

webSocketでパッケージを作成しています↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/2cd5b252-905d-c75c-4bec-c09341fa0114.png)

通信が成功すると101が返ってくるはず、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/4515980a-1d29-5c41-e5c3-ed8e59a45100.png)

デベロッパーツールで双方向のやりとりを見ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2689436/fc79c77c-4d7f-527e-965b-46007068d5aa.png)


## おわりに
javascript側でwebsocket通信を行う実装サンプルは豊富でしたが、javaでwebsocket通信を受け取る実装は試行錯誤を繰り返しました。
工夫すればチャットのようなリアルタイムで動作するアプリが作れそうですね。