具有多个ClientEndpoints和二进制消息的WebSocket

时间:2016-06-14 18:17:18

标签: java session mobile websocket codenameone

概述:

我目前拥有一个功能齐全的移动应用程序,它通过WebSockets与在Windows上运行的Java服务器进行通信。 ServerEndpoint正在运行AWS计算机。 Java服务器是在专用网络上运行的ClientEndpoint,在任何给定时间都可能有多个应用程序用户也是ClientEndpoints。

当涉及到来回发送String消息时,我目前正常运行,因为ServerEndpoint正在维护Java服务器会话以及移动应用程序Sessions。几乎所有通信都是通过移动应用程序启动的,此时JSON字符串被发送到Java服务器会话,以便能够维护哪个移动应用程序会话应该接收返回消息。

我现在正在尝试实现能够以相同的方式通过二进制消息从Java服务器向移动应用程序发送PDF文件的功能。移动应用程序是使用Codename One开发的,它们不提供增加最大二进制消息大小的能力,所以我似乎每个二进制消息限制为8kb(8,192字节)。这很好,因为我发送了多个二进制消息并在移动应用程序中重建文件。

我目前在最简单的情况下工作,一次只有一个移动应用程序用户请求PDF文件。

当前流程:

App A向ServerEndpoint发送JSON消息,然后将消息转发给Java服务器A. Java服务器A将JSON消息发送回ServerEndpoint,后者将消息转发回App A.JSON对象包含发送消息的会话ID回到。 ServerEndpoint需要知道将哪些App Session发送到来自Java服务器的消息。 当谈到二进制消息时,App A向ServerEndpoint发送一条String消息,然后将消息转发给Java服务器A. Java服务器A现在需要将多个二进制消息发送回ServerEndpoint,ALL必须转发给App A以获取该文件要正确重建。这是我不确定如何处理的部分。如果只有一个App会话,它目前工作正常,但如果多个App会话同时请求文件,它将无法正常工作。

问题:

发送String消息时,很容易来回传递回调移动应用程序会话ID作为JSON对象的一部分,以确保正确的移动应用程序会话获得响应。当发送二进制消息时,保证如果用户A和B同时请求文件的最佳方式是什么,用户A获取他/她请求的文件,用户B获取他/她请求的文件?

2 个答案:

答案 0 :(得分:2)

您应该能够跟踪会话而无需传递会话ID。例如,请参阅this sample web service endpoint

注意如何将Session对象作为带@OnMessage注释的第一个参数传递。

您可以使用它来了解您正在与谁交谈。

另一个小问题/问题。您的声明“移动应用程序是使用Codename One开发的,它们不能提供增加最大二进制消息大小的能力”,似乎建议其他平台允许您在客户端上设置最大二进制大小。 AFAIK这不是WebSocket规范的一部分,并且不是由任何浏览器实现的。还有哪些其他实现可以设置最大大小?

编辑回复您对问题的改进:

有多种方法可以为这只猫提供皮肤。一个想法是你只需要“最后一英里”(中间人和客户之间)。由于中间人和终端服务器是JavaEE服务器,因此您可以控制缓冲区大小,并且可以一次性发送完整文件(在合理范围内)。然后在中间服务器中进行分块,这将知道他正在处理哪个客户端。

另一种选择是创建自己的伪协议。您正在返回字节数组,但您可以选择分配每个块的前n个字节以包含元数据,中间人将解析出来。此元数据可用于告诉中间人该块的目的地是哪个客户端。

答案 1 :(得分:0)

压缩你要发送的文件并通过二进制文件发送,在服务器解压缩它以获取数据,我认为大小不是问题(虽然没有尝试过Codename One)。如果是,那么您可以将结构化的二进制数据块发送到具有类型和序列号的jason对象,您可以检查该数据以查找要发送的文件类型以及文件的块数。流程就像 得到chuncks - > Json对象(Type =“PDF”,SerialNumber =“1”,Data =“转换为字符串的二进制数据”) - >压缩json对象 - >发送到服务器。在服务器中执行相反的操作。