diff --git a/build.gradle b/build.gradle index 4d78ed7..d820de8 100644 --- a/build.gradle +++ b/build.gradle @@ -6,6 +6,7 @@ war { enabled = true archiveName 'cosmos.war' + baseName = 'websocket' } apply plugin: 'io.spring.dependency-management' @@ -31,4 +32,8 @@ compile("com.fasterxml.jackson.core:jackson-databind") compile("org.hibernate:hibernate-core:5.4.2.Final") compileOnly('org.projectlombok:lombok:1.16.10') + providedCompile 'javax.websocket:javax.websocket-api:1.1' + implementation 'org.glassfish.tyrus:tyrus-container-grizzly-server:1.13.1' + implementation 'com.squareup.okhttp3:okhttp:3.12.0' + implementation 'org.springframework.boot:spring-boot-starter-websocket' } diff --git a/src/main/java/com/example/cosmos_serversb/CosmosServerSbApplication.java b/src/main/java/com/example/cosmos_serversb/CosmosServerSbApplication.java index aaa3e30..416e897 100644 --- a/src/main/java/com/example/cosmos_serversb/CosmosServerSbApplication.java +++ b/src/main/java/com/example/cosmos_serversb/CosmosServerSbApplication.java @@ -2,10 +2,17 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Configuration; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.config.annotation.WebSocketConfigurer; +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; @SpringBootApplication +@Configuration +@EnableWebSocket public class CosmosServerSbApplication { - public static void main(String[] args) { SpringApplication.run(CosmosServerSbApplication.class, args); } diff --git a/src/main/java/com/example/cosmos_serversb/JerseyConfig.java b/src/main/java/com/example/cosmos_serversb/JerseyConfig.java index 37ef660..eb487d2 100644 --- a/src/main/java/com/example/cosmos_serversb/JerseyConfig.java +++ b/src/main/java/com/example/cosmos_serversb/JerseyConfig.java @@ -1,10 +1,13 @@ package com.example.cosmos_serversb; import javax.ws.rs.ApplicationPath; +import javax.ws.rs.Path; + import org.glassfish.jersey.server.ResourceConfig; import org.springframework.stereotype.Component; @Component +@ApplicationPath("/cosmos") public class JerseyConfig extends ResourceConfig { public JerseyConfig() { packages("com.example.cosmos_serversb.resources"); diff --git a/src/main/java/com/example/cosmos_serversb/WebSocketConfig.java b/src/main/java/com/example/cosmos_serversb/WebSocketConfig.java new file mode 100644 index 0000000..896a270 --- /dev/null +++ b/src/main/java/com/example/cosmos_serversb/WebSocketConfig.java @@ -0,0 +1,35 @@ +package com.example.cosmos_serversb; + +import com.example.cosmos_serversb.resources.WebSocket; +import lombok.AllArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.config.annotation.*; + + +@Configuration +@EnableWebSocket +@AllArgsConstructor +public class WebSocketConfig implements WebSocketConfigurer { + private final WebSocket websocket = new WebSocket(); + + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + registry.addHandler(websocket, "/websocket"); + } + +} + +//@Configuration +//@EnableWebSocketMessageBroker +//public class WebSocketConfig implements WebSocketConfigurer { +// @Override +// public void registerStompEndpoints(StompEndpointRegistry registry) { +// registry.addEndpoint("/websocket") +// .setAllowedOrigins("/websocket").withSockJS(); +// } +// @Override +// public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { +// registry.addHandler(websocket, "/endpoint"); +// } +// +//} \ No newline at end of file diff --git a/src/main/java/com/example/cosmos_serversb/resources/WebSocket.java b/src/main/java/com/example/cosmos_serversb/resources/WebSocket.java index a6d29ed..acf9183 100644 --- a/src/main/java/com/example/cosmos_serversb/resources/WebSocket.java +++ b/src/main/java/com/example/cosmos_serversb/resources/WebSocket.java @@ -1,15 +1,84 @@ package com.example.cosmos_serversb.resources; +import com.example.common.LogUtils; +import org.springframework.stereotype.Component; + import javax.websocket.*; import javax.websocket.server.ServerEndpoint; +import javax.ws.rs.GET; +import javax.ws.rs.Path; import java.io.IOException; import java.util.Queue; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.CopyOnWriteArraySet; +import org.springframework.stereotype.Component; +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; + +@Component @ServerEndpoint("/websocket") -public class WebSocket { +public class WebSocket extends TextWebSocketHandler { private static final Queue sessions = new ConcurrentLinkedQueue<>(); + private ConcurrentHashMap> roomSessionPool = new ConcurrentHashMap<>(); + public WebSocket(){ + + } + + @Override + public void afterConnectionEstablished(WebSocketSession session) throws Exception { + + String roomName = session.getUri().getQuery(); + + roomSessionPool.compute(roomName, (key, sessions) -> { + + if (sessions == null) { + sessions = new CopyOnWriteArraySet<>(); + } + sessions.add(session); + + return sessions; + }); + } + + @Override + protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { + + String roomName = session.getUri().getQuery(); + + for (WebSocketSession roomSession : roomSessionPool.get(roomName)) { + roomSession.sendMessage(message); + } + } + + @Override + public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { + + String roomName = session.getUri().getQuery(); + + roomSessionPool.compute(roomName, (key, sessions) -> { + + sessions.remove(session); + if (sessions.isEmpty()) { + // 1件もない場合はMapからクリア + sessions = null; + } + + return sessions; + }); + } + + + @GET + public String serverCheck() { + LogUtils.info("サーバーをチェックしています。"); + return "{\"ServerStatus\":\"200\"}"; + } @OnOpen public void onOpen(Session session) { /* セッション確立時の処理 */ @@ -49,3 +118,52 @@ }); } } + +//@ServerEndpoint(value = "/websocket") +//public class WebSocket { +// private static final Queue sessions = new ConcurrentLinkedQueue<>(); +// +// @GET +// public String serverCheck() { +// LogUtils.info("サーバーをチェックしています。"); +// return "{\"ServerStatus\":\"200\"}"; +// } +// @OnOpen +// public void onOpen(Session session) { +// /* セッション確立時の処理 */ +// sessions.add(session); +// System.out.println("WebSocketセッション確立"); +// } +// +// @OnMessage +// public String onMessage(String message) { +// /* メッセージ受信時の処理 */ +// System.out.println("WebSocket受信:" + message); +// return "正常にメッセージを受信しました。"; +// } +// +//// @OnMessage +//// public void onMessage(String message, Session session) throws IOException { +//// //session.getBasicRemote().sendText(message); //メッセージの送信が完了するまで待機 +//// session.getAsyncRemote().sendText(message); //非同期で送信 +//// } +// +// @OnError +// public void onError(Throwable th) { +// /* エラー発生時の処理 */ +// System.out.println("WebSocketエラー:" + th.getMessage()); +// } +// +// @OnClose +// public void onClose(Session session) { +// /* セッション解放時の処理 */ +// sessions.remove(session); +// System.out.println("WebSocketセッションを削除"); +// } +// +// public static void broadcast() { +// sessions.forEach(session -> { +// session.getAsyncRemote().sendText("Broadcast : "); +// }); +// } +//} diff --git a/src/test/java/WebSocketTest/SampleClient.java b/src/test/java/WebSocketTest/SampleClient.java index a7a49b1..0b07650 100644 --- a/src/test/java/WebSocketTest/SampleClient.java +++ b/src/test/java/WebSocketTest/SampleClient.java @@ -10,6 +10,60 @@ import javax.websocket.Session; import javax.websocket.WebSocketContainer; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.WebSocket; +import okhttp3.WebSocketListener; +import okio.ByteString; + +//public class SampleClient { +// public static void main(String[] args) { +// +// WebSocket ws; +// final Request request = new Request.Builder() +//// .url("http://localhost:8080/WebSocketSampleServer") +// .url("http://localhost:8080/websocket") +// .build(); +// final OkHttpClient client = new OkHttpClient.Builder() +// .build(); +// final WebSocketListener listener = new WebSocketListener() { +// @Override +// // 接続 +// public void onOpen(WebSocket webSocket, Response response) { +// } +// +// @Override +// //Serverからのメッセージの受信 +// public void onMessage(WebSocket webSocket, final String text) { +// } +// +// @Override +// public void onMessage(WebSocket webSocket, ByteString bytes) { +// System.out.println("MESSAGE: " + bytes.hex()); +// } +// +// @Override +// public void onClosing(WebSocket webSocket, int code, String reason) { +// webSocket.close(1000, null); +// System.out.println("CLOSE: " + code + " " + reason); +// } +// +// @Override +// //Serverの切断 +// public void onClosed(WebSocket webSocket, int code, String reason) { +// } +// +// public void onFailure(WebSocket webSocket, Throwable t, Response response) { +// t.printStackTrace(); +// } +// }; +// +// ws = client.newWebSocket(request, listener); +// client.dispatcher().executorService().shutdown(); +// } +//} + @ClientEndpoint public class SampleClient { diff --git a/src/test/java/hibernateTest/models/Groups.java b/src/test/java/hibernateTest/models/Groups.java index e95681f..7aaa2fc 100644 --- a/src/test/java/hibernateTest/models/Groups.java +++ b/src/test/java/hibernateTest/models/Groups.java @@ -2,7 +2,7 @@ import hibernateTest.entities.Group; import hibernateTest.entities.Request; -import com.example.cosmos_serversb.models.DeleteResult; +import com.example.cosmos_serversb.models.*; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.MetadataSources;