JAVA를 사용하여 Azure Web Pub Sub Service를 연결하여 간단한 MQ 데모 만들기

8009 단어 javapubsubazure

개요



네이티브 및 서버리스 WebSocket을 지원하는 완전 관리형 서비스인 Azure Web PubSub를 사용하여 실시간 메시징으로 웹 애플리케이션을 개발하세요. 게시-구독 메시징 패턴을 사용하여 느슨하게 결합되고 확장 가능한 애플리케이션(채팅, 라이브 스트리밍 및 IoT 대시보드 포함)을 생성합니다. Web PubSub가 웹 페이지 및 모바일 애플리케이션에 대한 데이터 및 콘텐츠 흐름을 관리하는 동안 개발자는 기능에 집중할 수 있습니다.

개념



연결하다



클라이언트 또는 클라이언트 연결이라고도 하는 연결은 Web PubSub 서비스에 대한 단일 WebSocket 연결을 나타냅니다. 성공적으로 연결되면 Web PubSub 서비스는 연결에 고유한 연결 ID를 할당합니다.

바퀴통



허브는 일련의 클라이언트 연결에 대한 논리적 개념입니다. 일반적으로 채팅 허브 또는 알림 허브와 같은 한 가지 용도로 허브를 사용합니다. 클라이언트가 연결되면 허브에 연결되고 평생 동안 해당 허브에 속합니다. 클라이언트가 허브에 연결되면 허브가 존재합니다. 서로 다른 애플리케이션은 서로 다른 허브 이름을 사용하여 Azure Web PubSub 서비스를 공유할 수 있습니다.

그룹



그룹은 허브에 대한 연결의 하위 집합입니다. 언제든지 그룹에 클라이언트 연결을 추가하거나 그룹에서 클라이언트 연결을 제거할 수 있습니다. 예를 들어 고객이 대화방에 들어오거나 고객이 대화방을 나갈 때 대화방을 그룹으로 간주할 수 있습니다. 클라이언트는 여러 그룹에 가입할 수 있으며 그룹에는 여러 클라이언트가 포함될 수 있습니다. 그룹은 그룹 "대화"와 같으며 그룹에 누군가가 가입하면 그룹 대화가 생성되고 그룹에 사람이 없으면 대화가 사라집니다.

사용자



Web PubSub에 대한 연결은 사용자에게 속할 수 있습니다. 사용자가 여러 장치 또는 여러 브라우저 탭에 연결하는 경우와 같이 사용자는 여러 연결을 가질 수 있습니다.

메시지



클라이언트가 연결되면 WebSocket 연결을 통해 업스트림 애플리케이션과 메시지를 주고받을 수 있습니다.

작업 과정


  • 클라이언트가 WebSocket 전송을 사용하여 서비스/클라이언트 끝점에 연결합니다. 서비스는 각 WebSocket 프레임을 구성된 업스트림(서버)으로 전달합니다. WebSocket 연결은 서버 처리를 위한 모든 사용자 지정 하위 프로토콜 또는 서비스에서 지원하는 하위 프로토콜 json.webpubsub.azure.v1과 연결하여 클라이언트가 직접 게시/구독할 수 있도록 합니다. 자세한 내용은 클라이언트 프로토콜에 설명되어 있습니다.
  • 서비스가 다른 클라이언트 이벤트에서 CloudEvents HTTP 프로토콜을 사용하여 서버를 호출합니다. CloudEvents는 CNCF(Cloud Native Computing Foundation)에서 호스팅하는 이벤트의 구조 및 메타데이터 설명에 대한 표준화된 프로토콜 독립적 정의입니다. 자세한 내용은 서버 프로토콜에 설명되어 있습니다.
  • 서버는 REST API를 사용하여 서비스를 호출하여 클라이언트에 메시지를 보내거나 연결된 클라이언트를 관리할 수 있습니다. 자세한 내용은 서버 프로토콜
  • 에 설명되어 있습니다.

    웹 게시 하위 서비스 만들기



    webPubSubServiceClient에 연결



    메이븐 가져오기




    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-messaging-webpubsub</artifactId>
        <version>1.1.4</version>
    </dependency>
    


    Azure에서 connectionString 가져오기 및 허브 결정




    WebPubSubServiceClient webPubSubServiceClient = new WebPubSubServiceClientBuilder()
            .connectionString(" ")
            .hub(" ")
            .buildClient();
    


    웹 소켓에 연결



    토큰 생성




    GetClientAccessTokenOptions getClientAccessTokenOptions = new GetClientAccessTokenOptions();
    getClientAccessTokenOptions.addRole("webpubsub.sendToGroup");
    getClientAccessTokenOptions.addRole("webpubsub.joinLeaveGroup");
    WebPubSubClientAccessToken token = webPubSubServiceClient.getClientAccessToken(getClientAccessTokenOptions);
    


    WebSocket 생성 및 사용된 데이터 전송 프로토콜 결정




    String url = token.getUrl();
    ws = HttpClient.newHttpClient().newWebSocketBuilder().subprotocols("json.webpubsub.azure.v1")
            .buildAsync(URI.create(url), new WebSocketClient()).join();
    


    WebSocket 메시지 리스너 구현(사용하는 WebSocket에 따라 구현 방법도 다름)




    private static final class WebSocketClient implements WebSocket.Listener {
        private WebSocketClient() {
        }
    
        @Override
        public void onOpen(WebSocket webSocket) {
            log.info("subscriber open");
            WebSocket.Listener.super.onOpen(webSocket);
        }
    
        @Override
        public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
            log.info("Message received:{}", data);
            return WebSocket.Listener.super.onText(webSocket, data, last);
        }
    
        @Override
        public void onError(WebSocket webSocket, Throwable error) {
            System.out.println("Bad day! " + webSocket.toString());
            WebSocket.Listener.super.onError(webSocket, error);
        }
    }
    
    


    정보



    AckId



    ackId를 사용하면 요청이 처리될 때 승인 응답 메시지를 받을 수 있습니다. fire-and-forget 시나리오에서 ackId를 생략하도록 선택할 수 있습니다.
    Web PubSub 서비스는 ackId가 있는 각 요청에 대해 ack 응답을 보냅니다.

    public class AckResponseMessage {
        private String type;
        private String ackId;
        private boolean success;
        private Error error;
    
        public static class Error{
            private String name;
            private String message;
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public String getMessage() {
                return message;
            }
    
            public void setMessage(String message) {
                this.message = message;
            }
        }
    }
    
    


    그룹으로 보내기




    public class SendGroupMessage {
        public final String type = "sendToGroup";
        public String data;
        public int ackId;
        public String group;
        public boolean noEcho;
        public DataType dataType;
    
        public SendGroupMessage(String data, int ackId, String group, boolean noEcho, DataType dataType) {
            this.data = data;
            this.ackId = ackId;
            this.group = group;
            this.noEcho = noEcho;
            this.dataType = dataType;
        }
    }
    
    


    그룹에 가입




    public class JoinGroupMessage {
        public int ackId;
        public final String type = "joinGroup";
        public String group;
    
        public JoinGroupMessage(int ackId, String group){
            this.ackId = ackId;
            this.group = group;
        }
    }
    


    그룹 탈퇴




    public class LeaveGroupMessage {
        public int ackId;
        public final String type = "leaveGroup";
        public String group;
    
        public LeaveGroupMessage(int ackId, String group){
            this.ackId = ackId;
            this.group = group;
        }
    }
    


    그룹에서 메시지 받기




    public class ReceivedGroupMessage {
        private String type;
        private String from;
        private String fromUserId;
        private String group;
        private DataType dataType;
        private String data;
    }
    


    서버에서 메시지 수신




    public class ReceivedServerMessage {
        private String type;
        private String from;
        private DataType dataType;
        private String data;
    }
    


    시스템 응답




    public class ConnectedSystemMessage {
        private String type;
        private String event;
        private String userId;
        private String connectionId;
    }
    
    public class DisConnectedSystemMessage {
         private String type;
         private String event;
         private String message;
    }
    


    게시 및 구독



    게시

    public void sendToGroup(String data,String group) {
         ++ackId;
         GroupMessage groupMessage = new GroupMessage(data, ackId, group);
         String string = null;
         try {
             string = objectMapper.writeValueAsString(groupMessage);
         } catch (JsonProcessingException e) {
             e.printStackTrace();
         }
         ws.sendText(string,true);
    }
    


    구독하다

    @Override
    public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
         try {
             String message = String.valueOf(data);
             handleData(message);
         } catch (Exception e) {
             log.warn("e:{}", e.getMessage());
         }
         return WebSocket.Listener.super.onText(webSocket, data, last);
    }
    

    좋은 웹페이지 즐겨찾기