Java即时通讯问题

Java即时通讯问题,java,sockets,instant-messaging,Java,Sockets,Instant Messaging,我希望用Java构建一个即时通讯器 客户端将连接到服务器以登录 他们将与一个或多个其他客户开始对话 然后,他们会将消息发布到服务器,服务器会将消息中继到所有客户端 当用户发布消息或登录时,客户端需要不断更新 因此,在我看来,客户端需要在一个单独的线程中运行服务器本身,以便主服务器可以向其发送内容。否则,客户端必须每隔xyz秒轮询主服务器以获取最新更新。这将需要一个单独的线程分析,因为这将纯粹用于获取更新,而“主”线程将用于客户端启动操作时,例如发布消息/邀请其他人参加对话等 有人推荐如何编写这个

我希望用Java构建一个即时通讯器

  • 客户端将连接到服务器以登录
  • 他们将与一个或多个其他客户开始对话
  • 然后,他们会将消息发布到服务器,服务器会将消息中继到所有客户端
  • 当用户发布消息或登录时,客户端需要不断更新

    因此,在我看来,客户端需要在一个单独的线程中运行服务器本身,以便主服务器可以向其发送内容。否则,客户端必须每隔xyz秒轮询主服务器以获取最新更新。这将需要一个单独的线程分析,因为这将纯粹用于获取更新,而“主”线程将用于客户端启动操作时,例如发布消息/邀请其他人参加对话等


    有人推荐如何编写这个即时通讯器吗?让客户端和服务器都充当服务器的连接成为“双向”连接听起来像是个好主意吗?还是投票是更好的选择?有人知道IRC协议是如何做到这一点的吗?

    如果您使用的是原始输入输出流,那么这是一种很好的方法。在客户端上创建一个线程,该线程的行为方式与服务器线程类似——等待任何传入的更新,并在更新时更新客户端。不过我不会把它叫做服务器。因此,理想情况下,您应该有两个TCP/UDP连接,一个用于客户端发出的请求,另一个用于通知客户端服务器的更改


    企业环境中的此解决方案可能通过某种消息传递框架(如Spring Integration)来实现,但深入研究后,本质上与您提到的方法类似。

    拥有两个连接没有真正的优势,除非它们可以独立处理(例如,接收/发送文件通常在单独的连接中完成)。连接本身已经是一个双向通信通道,因此它可以用于发送和接收消息、事件等。您不需要轮询服务器,因为客户端能够保持持久连接,只需等待数据出现(可选地发送周期性类似PING的消息,以确保连接处于活动状态)

    IRC使用到服务器的单一连接来交换文本命令。例如,一个主要命令:

    PRIVMSG <msgtarget> <message>
    
    PRIVMSG
    

    此命令可以由客户端或服务器发出。客户端发送
    PRIVMSG
    通知它要将消息传递到一个或多个目的地(在IRC中,此用户或通道)).Server在此的任务是将此消息正确地广播给适当的客户端。

    您需要一个完全自定义的协议还是使用XMPP就足够了?有几个开源库实现了XMPP。


    e、 g.

    对于我来说,为了开发即时消息服务,我将使用websocket协议而不是普通的java套接字,因为普通套接字不能与HTTP协议很好地配合,而且一些网络提供商和防火墙禁止自定义端口。如果在普通套接字中开发,web客户端将无法访问您的服务


    您是否计划自己开发即时消息服务?是否使用其他协议,例如?

    您说我不需要轮询服务器,但如何“等待数据出现”?客户端需要向服务器发送请求,以便服务器响应。这就是为什么我想使用两个连接,这样客户端就不会ave向服务器轮询接收更新的请求。@John McDonald如果客户端保持连接打开,则不必执行任何特殊的更新请求。向下到较低层,通过套接字上的正常读写操作发送和接收请求和响应。读操作将阻塞线程,直到数据恢复rrives(在经典的阻塞IO中)。是的,您可以称之为“长轮询”虽然它主要与HTTP-only通信有关,但套接字不直接可用。好吧,假设我按照您的建议只为客户端使用一个连接,正如您所说,读取操作将阻塞等待数据到达的线程。我遇到的问题是,如果正在侦听更新的读取操作阻塞,客户端如何向服务器发送请求?你是说让两个线程使用一个连接?因此,让一个线程阻止从服务器读取更新,并让另一个线程用于向服务器发送请求,例如“登录”/“添加朋友”/“发送消息”?两个线程可以使用一个连接吗?@John McDonal是的,多个线程可以读取或写入一个套接字,以确保在任何时候都不会在不同的线程中发生多个相同的操作。