관리 메뉴

너와 나의 스토리

Java로 websocket 통신하는 예제 + 삽질 기록 본문

Programming Language/Java

Java로 websocket 통신하는 예제 + 삽질 기록

노는게제일좋아! 2023. 9. 12. 23:33
반응형

JAVA 11로 websocket 통신 구현하기

1. Dependencies 추가

implementation group: 'javax.websocket', name: 'javax.websocket-api', version: '1.1'
implementation group: 'org.glassfish.tyrus', name: 'tyrus-server', version: '1.1'
implementation group: 'org.glassfish.tyrus', name: 'tyrus-client', version: '1.1'
implementation group: 'org.glassfish.tyrus', name: 'tyrus-container-grizzly', version: '1.1'

 

2. Client End Point 클래스 생성

import org.glassfish.tyrus.client.ClientManager;

import javax.websocket.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

@ClientEndpoint
public class WebSocketClient {

    private Logger logger = Logger.getLogger(this.getClass().getName());

    private final CountDownLatch latch;
    private Session session;

    public WebSocketClient() {
        this.latch = new CountDownLatch(1);
    }

    public boolean connect(String url) {
        ClientManager client = ClientManager.createClient();
        try {
            this.session = client.connectToServer(this, new URI(url));
            this.latch.await(2, TimeUnit.SECONDS);
            return session.isOpen();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public boolean isOpen(){
        return session.isOpen();
    }

    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
    }

    @OnMessage
    public String onMessage(String message, Session session) {
        BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));

        try {
            logger.info("Received ...." + message);
            String userInput = bufferRead.readLine();
            return userInput;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void send(byte[] data) {
        try {
            session.getBasicRemote().sendBinary(ByteBuffer.wrap(data));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void close() {
        try {
            if (session != null) {
                session.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

3. Websocket 연결

// 연결 & session 생성
WebSocketClient webSocketClient = new WebSocketClient();
webSocketClient.connect(serverUrl);

// 데이터 전송
webSocketClient.send(${data});

 

 

삽질 기록

1. Could not find an implementation class 에라 발생

implementation group: 'javax.websocket', name: 'javax.websocket-api', version: '1.1'
 WebSocketContainer container = ContainerProvider.getWebSocketContainer();
  • 'javax.websocket-api' dependency를 추가 후 WebSocketContainer()를 생성하려고 하니 다음과 같은 에러가 발생하였다.
Exception in thread "main" java.lang.RuntimeException: Could not find an implementation class.
at javax.websocket.ContainerProvider.getWebSocketContainer(ContainerProvider.java:73)
at connect.<init>(connect.java:21)
at test.main(test.java:11)

 

 

2. Connection refused

implementation group: 'org.glassfish.tyrus.bundles', name: 'tyrus-standalone-client', version: '1.10'
  • 위 dependency를 사용하니 1번에서 발생한 에러는 사라졌는데 socket 연결을 못함.
java.net.ConnectException: Connection refused
        at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
        at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:762)
        at org.glassfish.grizzly.nio.transport.TCPNIOConnectorHandler.onConnectedAsync(TCPNIOConnectorHandler.java:206)
        at org.glassfish.grizzly.nio.transport.TCPNIOConnectorHandler$1.connected(TCPNIOConnectorHandler.java:154)
        at org.glassfish.grizzly.nio.transport.TCPNIOConnection.onConnect(TCPNIOConnection.java:258)
        at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:552)
        at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.executeIoEvent(WorkerThreadIOStrategy.java:103)
        at org.glassfish.grizzly.strategies.AbstractIOStrategy.executeIoEvent(AbstractIOStrategy.java:89)
        at org.glassfish.grizzly.nio.SelectorRunner.iterateKeyEvents(SelectorRunner.java:414)
        at org.glassfish.grizzly.nio.SelectorRunner.iterateKeys(SelectorRunner.java:383)
        at org.glassfish.grizzly.nio.SelectorRunner.doSelect(SelectorRunner.java:347)
        at org.glassfish.grizzly.nio.SelectorRunner.run(SelectorRunner.java:278)
        at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
        at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
        at java.lang.Thread.run(Thread.java:1012)
  • version을 최신 버전인 2.1.3으로 올려도 동일한 문제 발생
jakarta.websocket.DeploymentException: Connection failed.
        at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientSocket._connect(GrizzlyClientSocket.java:419)
        at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientSocket.-$$Nest$m_connect(Unknown Source:0)
        at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientSocket$1.call(GrizzlyClientSocket.java:217)
        at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientSocket$1.call(GrizzlyClientSocket.java:213)
        at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientSocket.connect(GrizzlyClientSocket.java:231)
        at org.glassfish.tyrus.container.grizzly.client.GrizzlyClientContainer.openClientSocket(GrizzlyClientContainer.java:72)
        at org.glassfish.tyrus.client.ClientManager$3$1.run(ClientManager.java:647)
        at org.glassfish.tyrus.client.ClientManager$3.run(ClientManager.java:696)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:463)
        at java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at org.glassfish.tyrus.client.ClientManager$SameThreadExecutorService.execute(ClientManager.java:849)
        at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:118)
        at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:493)
        at orINFO: Renderer: metal
g.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:355)
        at com.genymobile.scrcpy.AudioWebSocketClient.<init>(AudioWebSocketClient.java:19)
        at com.genymobile.scrcpy.AudioCapture.<init>(AudioCapture.java:43)
        at com.genymobile.scrcpy.Server.scrcpy(Server.java:120)
        at com.genymobile.scrcpy.Server.main(Server.java:199)
        at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
        at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:378)
Caused by: java.net.ConnectException: Connection refused
        at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
        at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:762)
        at org.glassfish.grizzly.nio.transport.TCPNIOConnectorHandler.onConnectedAsync(TCPNIOConnectorHandler.java:175)
        at org.glassfish.grizzly.nio.transport.TCPNIOConnectorHandler$1.connected(TCPNIOConnectorHandler.java:132)
        at org.glassfish.grizzly.nio.transport.TCPNIOConnection.onConnect(TCPNIOConnection.java:220)

 

3. 다른 예제를 참고

  • dependency
implementation group: 'javax.websocket', name: 'javax.websocket-api', version: '1.1'
implementation group: 'org.glassfish.tyrus', name: 'tyrus-server', version: '1.1'
implementation group: 'org.glassfish.tyrus', name: 'tyrus-client', version: '1.1'
implementation group: 'org.glassfish.tyrus', name: 'tyrus-container-grizzly', version: '1.1'
  • ClientManager을 이용해서 client 객체 생성
ClientManager client = ClientManager.createClient();
this.session = client.connectToServer(this, serverURI);

 

반응형
Comments