Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Play2.5 Java WebSocket_Java_Websocket_Playframework 2.5 - Fatal编程技术网

Play2.5 Java WebSocket

Play2.5 Java WebSocket,java,websocket,playframework-2.5,Java,Websocket,Playframework 2.5,重头戏2.5突出显示各州 更好地控制WebSocket框架 Play 2.5 WebSocket API为您提供了对WebSocket框架的直接控制。您现在可以发送和接收二进制、文本、乒乓、乒乓和闭合帧。如果您不想担心这种详细程度,Play仍然会自动将JSON或XML数据转换为正确的帧类型 然而 有关于LegacyWebSocket的示例,该示例已被弃用 Java WebSocket的推荐API/模式是什么?正在使用 LegacyWebSocket是java WebSocket的唯一选项吗 有没

重头戏2.5突出显示各州

更好地控制WebSocket框架 Play 2.5 WebSocket API为您提供了对WebSocket框架的直接控制。您现在可以发送和接收二进制、文本、乒乓、乒乓和闭合帧。如果您不想担心这种详细程度,Play仍然会自动将JSON或XML数据转换为正确的帧类型

然而 有关于LegacyWebSocket的示例,该示例已被弃用

  • Java WebSocket的推荐API/模式是什么?正在使用 LegacyWebSocket是java WebSocket的唯一选项吗
  • 有没有使用新消息类型ping/pong实现心跳的示例

  • 令人失望的是,关于这一点的官方文件非常稀少。也许在游戏2.6中,我们会看到这方面的更新。不过,我将在下面提供一个示例,说明如何在Play2.5中配置聊天websocket,以帮助那些需要帮助的人

    安装程序 AController.java

    @Inject
    private Materializer materializer;
    private ActorRef chatSocketRouter;
    
    @Inject
    public AController(@Named("chatSocketRouter") ActorRef chatInjectedActor) {
        this.chatSocketRouter = chatInjectedActor;
    }
    
    
    // Make a chat websocket for a user
    public WebSocket chatSocket() {
    
        return WebSocket.Json.acceptOrResult(request -> {
            String authToken = getAuthToken();
    
            // Checking of token
            if (authToken == null) {
                return forbiddenResult("No [authToken] supplied.");
            }
    
            // Could we find the token in the database?
            final AuthToken token = AuthToken.findByToken(authToken);
            if (token == null) {
                return forbiddenResult("Could not find [authToken] in DB. Login again.");
            }
    
            User user = token.getUser();
            if (user == null) {
                return forbiddenResult("You are not logged in to view this stream.");
            }
    
            Long userId = user.getId();
    
            // Create a function to be run when we initialise a flow.
            // A flow basically links actors together.
            AbstractFunction1<ActorRef, Props> getWebSocketActor = new AbstractFunction1<ActorRef, Props>() {
                @Override
                public Props apply(ActorRef connectionProperties) {
    
                    // We use the ActorRef provided in the param above to make some properties.
                    // An ActorRef is a fancy word for thread reference.
                    // The WebSocketActor manages the web socket connection for one user.
                    // WebSocketActor.props() means "make one thread (from the WebSocketActor) and return the properties on how to reference it".
                    // The resulting Props basically state how to construct that thread.
                    Props properties = ChatSocketActor.props(connectionProperties, chatSocketRouter, userId);
    
                    // We can have many connections per user. So we need many ActorRefs (threads) per user. As you can see from the code below, we do exactly that. We have an object called
                    // chatSocketRouter which holds a Map of userIds -> connectionsThreads and we "tell"
                    // it a lightweight object (UserMessage) that is made up of this connecting user's ID and the connection.
                    // As stated above, Props are basically a way of describing an Actor, or dumbed-down, a thread.
    
                    // In this line, we are using the Props above to
                    // reference the ActorRef we've just created above
                    ActorRef anotherUserDevice = actorSystem.actorOf(properties);
                    // Create a lightweight object...
                    UserMessage routeThisUser = new UserMessage(userId, anotherUserDevice);
                    // ... to tell the thread that has our Map that we have a new connection
                    // from a user.
                    chatSocketRouter.tell(routeThisUser, ActorRef.noSender());
    
                    // We return the properties to the thread that will be managing this user's connection
                    return properties;
                }
            };
    
            final Flow<JsonNode, JsonNode, ?> jsonNodeFlow =
                    ActorFlow.<JsonNode, JsonNode>actorRef(getWebSocketActor,
                            100,
                            OverflowStrategy.dropTail(),
                            actorSystem,
                            materializer).asJava();
    
            final F.Either<Result, Flow<JsonNode, JsonNode, ?>> right = F.Either.Right(jsonNodeFlow);
            return CompletableFuture.completedFuture(right);
        });
    }
    
    // Return this whenever we want to reject a 
    // user from connecting to a websocket
    private CompletionStage<F.Either<Result, Flow<JsonNode, JsonNode, ?>>> forbiddenResult(String msg) {
        final Result forbidden = Results.forbidden(msg);
        final F.Either<Result, Flow<JsonNode, JsonNode, ?>> left = F.Either.Left(forbidden);
        return CompletableFuture.completedFuture(left);
    }
    
    public class ChatSocketActor extends UntypedActor {
    
        private final ActorRef out;
        private final Long userId;
        private ActorRef chatSocketRouter;
    
    
        public ChatSocketActor(ActorRef out, ActorRef chatSocketRouter, Long userId) {
            this.out = out;
            this.userId = userId;
            this.chatSocketRouter = chatSocketRouter;
        }
    
        public static Props props(ActorRef out, ActorRef chatSocketRouter, Long userId) {
            return Props.create(ChatSocketActor.class, out, chatSocketRouter, userId);
        }
    
        // Add methods here handling each chat connection...
    
    }
    
    public class ChatSocketRouter extends UntypedActor {
    
        public ChatSocketRouter() {}
    
    
        // Stores userIds to websockets
        private final HashMap<Long, List<ActorRef>> senders = new HashMap<>();
    
        private void addSender(Long userId, ActorRef actorRef){
            if (senders.containsKey(userId)) {
                final List<ActorRef> actors = senders.get(userId);
                actors.add(actorRef);
                senders.replace(userId, actors);
            } else {
                List<ActorRef> l = new ArrayList<>();
                l.add(actorRef);
                senders.put(userId, l);
            }
         }
    
    
         private void removeSender(ActorRef actorRef){
             for (List<ActorRef> refs : senders.values()) {
                 refs.remove(actorRef);
             }
         }
    
        @Override
        public void onReceive(Object message) throws Exception {
            ActorRef sender = getSender();
    
            // Handle messages sent to this 'router' here
    
            if (message instanceof UserMessage) {
                UserMessage userMessage = (UserMessage) message;
                addSender(userMessage.userId, userMessage.actorRef);
                // Watch sender so we can detect when they die.
                getContext().watch(sender);
            } else if (message instanceof Terminated) {
                // One of our watched senders has died.
                removeSender(sender);
    
            } else {
                unhandled(message);
            }
        }
    }
    
    private ActorRef chatSocketRouter;
    
    @Inject
    public ChatSenderController(@Named("chatSocketRouter") ActorRef chatInjectedActor) {
        this.chatSocketRouter = chatInjectedActor;
    }
    
    public static void sendMessage(Long sendToId) {
        // E.g. send the chat router a message that says hi
        chatSocketRouter.tell(new Message(sendToId, "Hi"));
    }
    
    @Override
    public void onReceive(Object message) throws Exception {
        // ...
    
        if (message instanceof Message) {
             Message messageToSend = (Message) message;
             // Loop through the list above and send the message to
             // each connection. For example...
             for (ActorRef wsConnection : senders.get(messageToSend.getSendToId())) {
                  // Send "Hi" to each of the other client's
                  // connected sessions
                  wsConnection.tell(messageToSend.getMessage());
             }
        }
    
        // ...
    }
    
    ChatSocketRouter.java

    @Inject
    private Materializer materializer;
    private ActorRef chatSocketRouter;
    
    @Inject
    public AController(@Named("chatSocketRouter") ActorRef chatInjectedActor) {
        this.chatSocketRouter = chatInjectedActor;
    }
    
    
    // Make a chat websocket for a user
    public WebSocket chatSocket() {
    
        return WebSocket.Json.acceptOrResult(request -> {
            String authToken = getAuthToken();
    
            // Checking of token
            if (authToken == null) {
                return forbiddenResult("No [authToken] supplied.");
            }
    
            // Could we find the token in the database?
            final AuthToken token = AuthToken.findByToken(authToken);
            if (token == null) {
                return forbiddenResult("Could not find [authToken] in DB. Login again.");
            }
    
            User user = token.getUser();
            if (user == null) {
                return forbiddenResult("You are not logged in to view this stream.");
            }
    
            Long userId = user.getId();
    
            // Create a function to be run when we initialise a flow.
            // A flow basically links actors together.
            AbstractFunction1<ActorRef, Props> getWebSocketActor = new AbstractFunction1<ActorRef, Props>() {
                @Override
                public Props apply(ActorRef connectionProperties) {
    
                    // We use the ActorRef provided in the param above to make some properties.
                    // An ActorRef is a fancy word for thread reference.
                    // The WebSocketActor manages the web socket connection for one user.
                    // WebSocketActor.props() means "make one thread (from the WebSocketActor) and return the properties on how to reference it".
                    // The resulting Props basically state how to construct that thread.
                    Props properties = ChatSocketActor.props(connectionProperties, chatSocketRouter, userId);
    
                    // We can have many connections per user. So we need many ActorRefs (threads) per user. As you can see from the code below, we do exactly that. We have an object called
                    // chatSocketRouter which holds a Map of userIds -> connectionsThreads and we "tell"
                    // it a lightweight object (UserMessage) that is made up of this connecting user's ID and the connection.
                    // As stated above, Props are basically a way of describing an Actor, or dumbed-down, a thread.
    
                    // In this line, we are using the Props above to
                    // reference the ActorRef we've just created above
                    ActorRef anotherUserDevice = actorSystem.actorOf(properties);
                    // Create a lightweight object...
                    UserMessage routeThisUser = new UserMessage(userId, anotherUserDevice);
                    // ... to tell the thread that has our Map that we have a new connection
                    // from a user.
                    chatSocketRouter.tell(routeThisUser, ActorRef.noSender());
    
                    // We return the properties to the thread that will be managing this user's connection
                    return properties;
                }
            };
    
            final Flow<JsonNode, JsonNode, ?> jsonNodeFlow =
                    ActorFlow.<JsonNode, JsonNode>actorRef(getWebSocketActor,
                            100,
                            OverflowStrategy.dropTail(),
                            actorSystem,
                            materializer).asJava();
    
            final F.Either<Result, Flow<JsonNode, JsonNode, ?>> right = F.Either.Right(jsonNodeFlow);
            return CompletableFuture.completedFuture(right);
        });
    }
    
    // Return this whenever we want to reject a 
    // user from connecting to a websocket
    private CompletionStage<F.Either<Result, Flow<JsonNode, JsonNode, ?>>> forbiddenResult(String msg) {
        final Result forbidden = Results.forbidden(msg);
        final F.Either<Result, Flow<JsonNode, JsonNode, ?>> left = F.Either.Left(forbidden);
        return CompletableFuture.completedFuture(left);
    }
    
    public class ChatSocketActor extends UntypedActor {
    
        private final ActorRef out;
        private final Long userId;
        private ActorRef chatSocketRouter;
    
    
        public ChatSocketActor(ActorRef out, ActorRef chatSocketRouter, Long userId) {
            this.out = out;
            this.userId = userId;
            this.chatSocketRouter = chatSocketRouter;
        }
    
        public static Props props(ActorRef out, ActorRef chatSocketRouter, Long userId) {
            return Props.create(ChatSocketActor.class, out, chatSocketRouter, userId);
        }
    
        // Add methods here handling each chat connection...
    
    }
    
    public class ChatSocketRouter extends UntypedActor {
    
        public ChatSocketRouter() {}
    
    
        // Stores userIds to websockets
        private final HashMap<Long, List<ActorRef>> senders = new HashMap<>();
    
        private void addSender(Long userId, ActorRef actorRef){
            if (senders.containsKey(userId)) {
                final List<ActorRef> actors = senders.get(userId);
                actors.add(actorRef);
                senders.replace(userId, actors);
            } else {
                List<ActorRef> l = new ArrayList<>();
                l.add(actorRef);
                senders.put(userId, l);
            }
         }
    
    
         private void removeSender(ActorRef actorRef){
             for (List<ActorRef> refs : senders.values()) {
                 refs.remove(actorRef);
             }
         }
    
        @Override
        public void onReceive(Object message) throws Exception {
            ActorRef sender = getSender();
    
            // Handle messages sent to this 'router' here
    
            if (message instanceof UserMessage) {
                UserMessage userMessage = (UserMessage) message;
                addSender(userMessage.userId, userMessage.actorRef);
                // Watch sender so we can detect when they die.
                getContext().watch(sender);
            } else if (message instanceof Terminated) {
                // One of our watched senders has died.
                removeSender(sender);
    
            } else {
                unhandled(message);
            }
        }
    }
    
    private ActorRef chatSocketRouter;
    
    @Inject
    public ChatSenderController(@Named("chatSocketRouter") ActorRef chatInjectedActor) {
        this.chatSocketRouter = chatInjectedActor;
    }
    
    public static void sendMessage(Long sendToId) {
        // E.g. send the chat router a message that says hi
        chatSocketRouter.tell(new Message(sendToId, "Hi"));
    }
    
    @Override
    public void onReceive(Object message) throws Exception {
        // ...
    
        if (message instanceof Message) {
             Message messageToSend = (Message) message;
             // Loop through the list above and send the message to
             // each connection. For example...
             for (ActorRef wsConnection : senders.get(messageToSend.getSendToId())) {
                  // Send "Hi" to each of the other client's
                  // connected sessions
                  wsConnection.tell(messageToSend.getMessage());
             }
        }
    
        // ...
    }
    
    ChatSocketRouter.java

    @Inject
    private Materializer materializer;
    private ActorRef chatSocketRouter;
    
    @Inject
    public AController(@Named("chatSocketRouter") ActorRef chatInjectedActor) {
        this.chatSocketRouter = chatInjectedActor;
    }
    
    
    // Make a chat websocket for a user
    public WebSocket chatSocket() {
    
        return WebSocket.Json.acceptOrResult(request -> {
            String authToken = getAuthToken();
    
            // Checking of token
            if (authToken == null) {
                return forbiddenResult("No [authToken] supplied.");
            }
    
            // Could we find the token in the database?
            final AuthToken token = AuthToken.findByToken(authToken);
            if (token == null) {
                return forbiddenResult("Could not find [authToken] in DB. Login again.");
            }
    
            User user = token.getUser();
            if (user == null) {
                return forbiddenResult("You are not logged in to view this stream.");
            }
    
            Long userId = user.getId();
    
            // Create a function to be run when we initialise a flow.
            // A flow basically links actors together.
            AbstractFunction1<ActorRef, Props> getWebSocketActor = new AbstractFunction1<ActorRef, Props>() {
                @Override
                public Props apply(ActorRef connectionProperties) {
    
                    // We use the ActorRef provided in the param above to make some properties.
                    // An ActorRef is a fancy word for thread reference.
                    // The WebSocketActor manages the web socket connection for one user.
                    // WebSocketActor.props() means "make one thread (from the WebSocketActor) and return the properties on how to reference it".
                    // The resulting Props basically state how to construct that thread.
                    Props properties = ChatSocketActor.props(connectionProperties, chatSocketRouter, userId);
    
                    // We can have many connections per user. So we need many ActorRefs (threads) per user. As you can see from the code below, we do exactly that. We have an object called
                    // chatSocketRouter which holds a Map of userIds -> connectionsThreads and we "tell"
                    // it a lightweight object (UserMessage) that is made up of this connecting user's ID and the connection.
                    // As stated above, Props are basically a way of describing an Actor, or dumbed-down, a thread.
    
                    // In this line, we are using the Props above to
                    // reference the ActorRef we've just created above
                    ActorRef anotherUserDevice = actorSystem.actorOf(properties);
                    // Create a lightweight object...
                    UserMessage routeThisUser = new UserMessage(userId, anotherUserDevice);
                    // ... to tell the thread that has our Map that we have a new connection
                    // from a user.
                    chatSocketRouter.tell(routeThisUser, ActorRef.noSender());
    
                    // We return the properties to the thread that will be managing this user's connection
                    return properties;
                }
            };
    
            final Flow<JsonNode, JsonNode, ?> jsonNodeFlow =
                    ActorFlow.<JsonNode, JsonNode>actorRef(getWebSocketActor,
                            100,
                            OverflowStrategy.dropTail(),
                            actorSystem,
                            materializer).asJava();
    
            final F.Either<Result, Flow<JsonNode, JsonNode, ?>> right = F.Either.Right(jsonNodeFlow);
            return CompletableFuture.completedFuture(right);
        });
    }
    
    // Return this whenever we want to reject a 
    // user from connecting to a websocket
    private CompletionStage<F.Either<Result, Flow<JsonNode, JsonNode, ?>>> forbiddenResult(String msg) {
        final Result forbidden = Results.forbidden(msg);
        final F.Either<Result, Flow<JsonNode, JsonNode, ?>> left = F.Either.Left(forbidden);
        return CompletableFuture.completedFuture(left);
    }
    
    public class ChatSocketActor extends UntypedActor {
    
        private final ActorRef out;
        private final Long userId;
        private ActorRef chatSocketRouter;
    
    
        public ChatSocketActor(ActorRef out, ActorRef chatSocketRouter, Long userId) {
            this.out = out;
            this.userId = userId;
            this.chatSocketRouter = chatSocketRouter;
        }
    
        public static Props props(ActorRef out, ActorRef chatSocketRouter, Long userId) {
            return Props.create(ChatSocketActor.class, out, chatSocketRouter, userId);
        }
    
        // Add methods here handling each chat connection...
    
    }
    
    public class ChatSocketRouter extends UntypedActor {
    
        public ChatSocketRouter() {}
    
    
        // Stores userIds to websockets
        private final HashMap<Long, List<ActorRef>> senders = new HashMap<>();
    
        private void addSender(Long userId, ActorRef actorRef){
            if (senders.containsKey(userId)) {
                final List<ActorRef> actors = senders.get(userId);
                actors.add(actorRef);
                senders.replace(userId, actors);
            } else {
                List<ActorRef> l = new ArrayList<>();
                l.add(actorRef);
                senders.put(userId, l);
            }
         }
    
    
         private void removeSender(ActorRef actorRef){
             for (List<ActorRef> refs : senders.values()) {
                 refs.remove(actorRef);
             }
         }
    
        @Override
        public void onReceive(Object message) throws Exception {
            ActorRef sender = getSender();
    
            // Handle messages sent to this 'router' here
    
            if (message instanceof UserMessage) {
                UserMessage userMessage = (UserMessage) message;
                addSender(userMessage.userId, userMessage.actorRef);
                // Watch sender so we can detect when they die.
                getContext().watch(sender);
            } else if (message instanceof Terminated) {
                // One of our watched senders has died.
                removeSender(sender);
    
            } else {
                unhandled(message);
            }
        }
    }
    
    private ActorRef chatSocketRouter;
    
    @Inject
    public ChatSenderController(@Named("chatSocketRouter") ActorRef chatInjectedActor) {
        this.chatSocketRouter = chatInjectedActor;
    }
    
    public static void sendMessage(Long sendToId) {
        // E.g. send the chat router a message that says hi
        chatSocketRouter.tell(new Message(sendToId, "Hi"));
    }
    
    @Override
    public void onReceive(Object message) throws Exception {
        // ...
    
        if (message instanceof Message) {
             Message messageToSend = (Message) message;
             // Loop through the list above and send the message to
             // each connection. For example...
             for (ActorRef wsConnection : senders.get(messageToSend.getSendToId())) {
                  // Send "Hi" to each of the other client's
                  // connected sessions
                  wsConnection.tell(messageToSend.getMessage());
             }
        }
    
        // ...
    }
    

    同样,我写上面的内容是为了帮助那些需要帮助的人。在浏览网页之后,我找不到一个合理而简单的例子。对于这个确切的主题,有一个明确的定义。网上也有一些,但没有一个是容易遵循的。Akka有一些很棒的文档,但将其与游戏结合起来是一项艰巨的精神任务


    如果您发现任何问题,请帮助改进此答案。

    也希望看到发送闭合帧的示例。也没有在文档中找到任何内容。可能的副本似乎有一个名为WebSocket的新类替换了它。您可能需要查看一下