DEV Community 👩‍💻👨‍💻

Skye HAN
Skye HAN

Posted on • Updated on

Use JAVA to connect Azure Web Pub Sub Service to make a simple MQ Demo

Overview

Develop web applications with real-time messaging using Azure Web PubSub, a fully managed service that supports native and serverless WebSockets. Use the publish-subscribe messaging pattern to create loosely coupled, scalable applications - including chat, live streaming, and IoT dashboards. Developers can focus on functionality while Web PubSub manages the flow of data and content to your web pages and mobile applications.

concept

connect

A connection, also known as a client or client connection, represents a single WebSocket connection to a Web PubSub service. After a successful connection, the Web PubSub service assigns a unique connection ID to the connection.

hub

A hub is a logical concept for a set of client connections. Usually you use a hub for one purpose, for example, a chat hub or a notification hub. When a client connects, it connects to a hub, and for the life of its life, it belongs to that hub. Once a client connects to the hub, the hub exists. Different applications can share an Azure Web PubSub service using different hub names.

Group

A group is a subset of connections to a hub. You can add client connections to or remove client connections from a group at any time. For example, when a customer joins a chat room, or when a customer leaves the chat room, the chat room can be considered a group. A client can join multiple groups, and a group can contain multiple clients. A group is like a group "conversation", a group conversation is created once someone joins the group, and the conversation disappears when there is no one in the group.

user

A connection to Web PubSub can belong to a user. A user may have multiple connections, such as when a user connects across multiple devices or multiple browser tabs.

message

When a client connects, it can send messages to, or receive messages from, upstream applications over the WebSocket connection.

work process

  1. The client connects to the service/client endpoint using the WebSocket transport. The service forwards each WebSocket frame to the configured upstream (server). WebSocket connections can connect with any custom subprotocol for server processing, or with the subprotocol json.webpubsub.azure.v1 supported by the service, which enables clients to pub/sub directly. Details are described in Client Protocol.
  2. The service calls the server using the CloudEvents HTTP protocol on different client events. CloudEvents is a standardized, protocol-agnostic definition of the structure and metadata description of events hosted by the Cloud Native Computing Foundation (CNCF). Details are described in the server protocol.
  3. The server can use the REST API to call services to send messages to clients or manage connected clients. Details are described in the server protocol

Create a web pub sub service

Connect to webPubSubServiceClient

Import maven

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-messaging-webpubsub</artifactId>
    <version>1.1.4</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Get connectionString from Azure and determine Hub

WebPubSubServiceClient webPubSubServiceClient = new WebPubSubServiceClientBuilder()
        .connectionString(" ")
        .hub(" ")
        .buildClient();
Enter fullscreen mode Exit fullscreen mode

Connect to webSocket

Create token

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

Create a WebSocket and determine the data transfer protocol used

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

Implement WebSocket message listener (depending on the WebSocket used, the implementation method is also different)

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);
    }
}

Enter fullscreen mode Exit fullscreen mode

Information

AckId

When using ackId, you can receive an acknowledgment response message when your request is processed. You can choose to omit the ackId in fire-and-forget scenarios.
The Web PubSub service will send an ack response for each request with an ackId.

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;
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

Send to group

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;
    }
}

Enter fullscreen mode Exit fullscreen mode

Join a group

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;
    }
}
Enter fullscreen mode Exit fullscreen mode

Leave a 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;
    }
}
Enter fullscreen mode Exit fullscreen mode

Receiving messages from groups

public class ReceivedGroupMessage {
    private String type;
    private String from;
    private String fromUserId;
    private String group;
    private DataType dataType;
    private String data;
}
Enter fullscreen mode Exit fullscreen mode

Receiving a message from the server

public class ReceivedServerMessage {
    private String type;
    private String from;
    private DataType dataType;
    private String data;
}
Enter fullscreen mode Exit fullscreen mode

System response

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;
}
Enter fullscreen mode Exit fullscreen mode

Publish and subscribe

Publish

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);
}
Enter fullscreen mode Exit fullscreen mode

Subscribe

@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);
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)

🌚 Life is too short to browse without dark mode