使用 Akka 和 Websockets 玩框架

Posted

技术标签:

【中文标题】使用 Akka 和 Websockets 玩框架【英文标题】:Play Framework with Akka and Websockets 【发布时间】:2013-04-17 05:12:15 【问题描述】:

我通过 Play 2.1 建立了一个简单的 websocket 连接设置,连接到一个 javascript 前端。

我在服务器上有一个随机数生成循环,它生成一个随机数并通过 websocket 发送出去。随机数生成是在一个无休止的 while 循环中执行的。我创建了一个 Akka Actor,它只是通过创建的 websocket 发送它接收到的消息。

问题

在每次迭代中生成要通过 websocket 发送的随机数的 while 循环中,它永远不会通过 websocket 发送任何内容。当我实际限制循环以使其实际结束时,所有生成的数字都在 while 循环结束时发送,并且在每次迭代中实际上并不实时发送。我不知道如何让它工作,以便它在每次迭代中发送。

参见下面的代码。

具有随机数生成器功能的应用程序框架

  public class Application extends Controller 


// Default MqTT Messages Actor
static ActorRef defaultMqttActor = Akka.system().actorOf(new Props(WebsocketHandle.class));



public static WebSocket<String> realTimeChartConnection() 
    return new WebSocket<String>() 
        // called when the websocket is established
        public void onReady(WebSocket.In<String> in,
                WebSocket.Out<String> out) 
            // register a callback for processing instream events
            in.onMessage(new Callback<String>() 
                public void invoke(String event) 
                    System.out.println(event);
                
            );

            System.out.println("Websocket Connection ready ...");

            WebsocketHandle.setWebsocketOut(out);
            sendRandomNumbers();

        
    ;


public static void sendRandomNumbers() 

    int prev = 50;
    while (true) 
        int y = (int) (prev + Math.random() * 10 - 5);
        if (y < 0)
            y = 0;
        if (y > 100)
            y = 100;

        defaultMqttActor.tell(""+y);
        System.out.println(""+y);
        try 
            Thread.currentThread();
            Thread.sleep(30);
         catch (Exception e) 
            System.out.println(e.getStackTrace());
        
    

WebsocketHandle Actor 代码

static ActorRef defaultMqttActor = Akka.system().actorOf(new Props(WebsocketHandle.class));

WebsocketHandle

public class WebsocketHandle extends UntypedActor 

public static WebSocket.Out<String> outStream;

    public static void setWebsocketOut(WebSocket.Out<String> out)
       outStream = out;
    

    public void onReceive(Object message) throws Exception 

       outStream.write((String)message);

    

如您所见,actor 只是发送它在“onReceive”中接收到的消息。随机数生成循环只是“告诉”生成的数字。我不明白为什么它不通过 websocket 异步发送消息。

似乎 Websocket 正在缓冲结果......我怎样才能让 websocket 立即发送数据?

【问题讨论】:

如果它与您的问题相似,我不会,但请注意这些静态方法,尤其是您的演员中的setWebsocketOut。请显示更多代码。 我现在已经添加了完整的代码。虽然它没有告诉你任何新的东西......我所拥有的只是我正在使用的核心功能,但现在我正在展示整个 application.java。这是所有的代码。 【参考方案1】:

我怀疑,由于您从 WebSocket 响应的 onReady 方法中启动了一个无限循环,因此它的线程永远不会被释放,并且消息会排队并且永远不会发送,直到循环结束。

您正在寻找的可能是调度程序。它允许以固定的时间间隔或延迟后向参与者发送消息。 改编自 Akka 官方文档:http://doc.akka.io/docs/akka/snapshot/java/scheduler.html

Akka.system().scheduler().schedule(Duration.create(50, TimeUnit.MILLISECONDS),
  new Runnable() 
    @Override
    public void run() 
      defaultMqttActor.tell("" + Math.random() * 10 + 5, null);
    
, system.dispatcher());

【讨论】:

以上是关于使用 Akka 和 Websockets 玩框架的主要内容,如果未能解决你的问题,请参考以下文章

Akka 框架支持查找重复消息

Scala并发框架Akka原理详解

Akka中使用Logback日志框架

Akka框架使用注意点

Scala框架Akka学习

Scala-Unit7-Scala并发编程模型AKKA