Java - Play2是WebSockets实现所需的Actors吗?

Pop*_*ibo 12 java websocket playframework playframework-2.0

我正在尝试使用Play2和Java实现基于WebSockets的解决方案.目前我没有使用Actor Model进行并发管理.相反,它只是使用回调来处理WebSockets.

问题是服务器无法将消息"广播"到多个客户端.例如,我需要所有活动的浏览器会话在通过客户端触发操作后接收简单通知.相反,我只能在单个客户端会话中模拟这个.实际上,它只是作为常规Ajax请求/响应方案.

我的猜测是带有简单回调的Play2和Java的WebSockets解决方案无法将消息广播到所有连接的客户端浏览器.

回调服务器代码

public static WebSocket<String> heartUpdate() {
        return new WebSocket<String>() {
            public void onReady(final WebSocket.In<String> in,
                    WebSocket.Out<String> out) {
                in.onMessage(new Callback<String>() {
                    @Override
                    public void invoke(String event) throws Throwable {
                        Product product = Product.find.byId(Long.decode(event));
                        // Other business stuff
                        out.write(entity.id + " " + decimalValue);
                    }
                });
                in.onClose(new Callback0() {
                    @Override
                    public void invoke() throws Throwable {

                    }
                });
                out.write(DELIM_USERID_REP);
            }
        };
    }
Run Code Online (Sandbox Code Playgroud)

路线入口

GET /repsocket   controllers.Application.heartUpdate
Run Code Online (Sandbox Code Playgroud)

客户端

<script>
    // Onto the WebSockets now
    var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket;
    var socket = new WS("@routes.Application.heartUpdate.webSocketURL(request)");

    var receiveEvent = function(event) {
        alert(event.data);
        // Notification badge visible with a common text
        $('#notify').text(event.data);
        $('#notify').addClass('visible');
    }
        $('#heart').click(function(e) {
            e.preventDefault();
            socket.send(@product.id);
        });
    socket.onmessage = receiveEvent;
    </script>
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,动作触发客户端是从服务器成功接收消息的动作,而任何其他浏览器会话则不是.

我没有找到任何与使用Java和WebSockets的Play2一致的文档,建议强制使用Actors来维护与所有连接的活动客户端的一致通信.

问题: Play2 with Java中的WebSockets是否应该使用Actor Model实现,以便将消息广播到所有活动的客户端会话?

编辑: 下面的屏幕截图反映了我使用2个有效用户凭据登录的浏览器的2种状态.

理想情况下,WebSockets从服务器的响应应该在两个浏览器上创建相同的通知标记.

在此输入图像描述

Sal*_*lem 5

查看您发布的代码,似乎问题是您没有保存对每个连接的引用,因此您可以稍后广播消息.像这样的东西:

// Just an example: does not deal with concurrency problems
private static final Set<WebSocket.Out<String>> SOCKETS = new HashSet<>();

public static WebSocket<String> heartUpdate() {
    return new WebSocket<String>() {
        public void onReady(final WebSocket.In<String> in,
                    final WebSocket.Out<String> out) {
            SOCKETS.add(out);
            in.onMessage(new Callback<String>() {
                @Override
                public void invoke(String event) throws Throwable {
                    for(WebSocket.Out<String> s: SOCKETS) {
                        s.write("SOME MESSAGE");    
                    }
                }
            });
            in.onClose(new Callback0() {
                @Override
                public void invoke() throws Throwable {
                    SOCKETS.remove(out);
                }
            });
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

您还可以使用actor来模拟此问题:让演员负责跟踪连接并处理新的套接字连接/关闭.

如果您想使用Akka,可以使用一些激活模板来帮助您入门.