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

Java 具有多个ClientEndpoints和二进制消息的WebSocket,java,session,mobile,websocket,codenameone,Java,Session,Mobile,Websocket,Codenameone,概述: 我目前有一个功能齐全的移动应用程序,可以通过WebSocket与运行在Windows上的Java服务器进行通信。ServerEndpoint正在AWS计算机上运行。Java服务器是一个在专用网络上运行的客户端,在任何给定时间都可以有多个应用程序用户也是客户端 目前,当涉及来回发送字符串消息时,我的一切都正常工作,因为ServerEndpoint正在维护Java服务器会话和移动应用程序会话。几乎所有通信都是通过移动应用程序启动的,此时一个JSON字符串被发送到Java服务器会话,以便能够维

概述:

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

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

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

我目前在一个最简单的情况下就可以做到这一点,即一次只有一个移动应用程序用户请求PDF文件

当前流量:

应用程序A将JSON消息发送给ServerEndpoint,后者将消息转发给Java服务器A。Java服务器A将JSON消息发送回ServerEndpoint,后者将消息转发回应用程序A。JSON对象包含要将消息发送回的会话id。ServerEndpoint需要知道从Java服务器向哪个应用程序会话发送消息。 当涉及到二进制消息时,应用程序A向ServerEndpoint发送一条字符串消息,然后将消息转发给Java server A。Java server A现在需要将多条二进制消息发送回ServerEndpoint,所有这些消息都必须转发给应用程序A才能正确重建文件。这是我不确定如何处理的部分。如果只有一个应用程序会话,它目前可以正常工作,但是如果多个应用程序会话同时请求文件,它将无法正常工作

问题:


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

您应该能够跟踪会话,而不必传递会话ID。例如,请参阅

请注意如何使用
@OnMessage
注释将
会话
对象作为第一个参数传递

你可以用这个来知道你在跟谁说话

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

根据您对问题的细化进行编辑:

给这只猫剥皮有多种方法。一个想法是,你只需要在“最后一英里”(中间人和客户之间)上下功夫。因为中间人和终端服务器都是JavaEE服务器,所以您可以控制缓冲区的大小,并且可以一次发送完整的文件(在合理的范围内)。然后只需在中间服务器上进行组块,就可以知道他在处理哪个客户。


另一个选择是创建自己的伪协议。您将返回字节数组,但您可以选择分配每个块的前n个字节以包含元数据,中间人将解析出元数据。这个元数据可以用来告诉中间人区块将要发送到哪个客户机。

压缩要发送的文件并通过二进制文件发送,在服务器中解压以获取数据,我认为大小没有问题(不过还没有尝试使用Codename One)。如果是,那么您可以将二进制数据块发送到jason对象,该对象具有一个类型和序列号,您可以检查该类型和序列号,以查找您要发送的文件的类型和文件块的数量。流动将是这样的
获取chuncks->Json对象(Type=“PDF”,SerialNumber=“1”,Data=“Binary Data converted to String”)->压缩Json对象->发送到服务器。在服务器中执行相反的操作。

我已经请Steve回答这个问题。谢谢,尽管我认为这实际上更像是一个WebSocket问题,而不是任何错误或无法在cn1中工作的问题。谢谢,我会看一看。另外,我在这里看到了关于设置最大大小的规范:我刚刚编辑了我的问题,其中包含了关于当前流的更多细节。基本上,ServerEndpoint目前扮演着中间人的角色。实际上,我最终实现了第二个选项,我很高兴你提出了这个建议,因为我有点谨慎。谢谢你的帮助!因此,在所有这些之后,似乎是我的ServerEndpoint导致了这些问题。使用注释@OnMessage(maxMessageSize=10000000)可以在单个消息中发送文件。我想是很好的学习经验吧?