所以,我正在尝试一下Kryonet库,并开始我决定开发一个简单的聊天程序,允许从客户端(远程计算机)到服务器进行通信(本地机器)。
一切似乎都有效,我能够从客户端接收消息到我的服务器。
但是有一个很烦人的问题:如果客户端在一段时间内没有发送任何数据包(这里的数据包是文本消息),他会被服务器断开连接,说他超时了。 / p>
我正在努力解决这个问题而且我不知道如何解决这个问题......
以下是我的程序的来源(除了//all my imports
注释掉,以避免有大量的导入行...):
ChattyServer.java
package com.azsde.Chatty;
//all my imports
public class ChattyServer {
//Mes objets
private Server server;
private ArrayList <Clients> clientsList;
//Mes méthodes
//Constructeur
public ChattyServer() throws IOException
{
clientsList = new ArrayList <Clients>();
server = new Server();
registerPackets();
server.addListener(new NetworkListener(clientsList));
server.bind(101);
server.start();
// Open a window to provide an easy way to stop the server.
JFrame frame = new JFrame("Chatty Server");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter()
{
public void windowClosed (WindowEvent evt)
{
server.stop();
}
});
frame.getContentPane().add(new JLabel("Close to stop the server."));
JPanel panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.SOUTH);
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//Packet3Order order = new Packet3Order();
//order.start = true;
//server.getConnections()[0].sendTCP(order);
listClients();
}
});
panel.add(btnNewButton);
frame.setSize(320, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void registerPackets()
{
Kryo kryo = server.getKryo();
kryo.register(Packet0ConnectionRequest.class);
kryo.register(Packet1RequestResponse.class);
kryo.register(Packet2Message.class);
kryo.register(Packet3Order.class);
}
private void listClients()
{
for (int i = 0 ; i < clientsList.size() ; i ++)
{
if (!clientsList.isEmpty())
{
System.out.println(clientsList.get(i).getUsername());
System.out.println(clientsList.get(i).getIpAdress());
}
}
}
public static void main (String[] args) {
try {
new ChattyServer();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.set(Log.LEVEL_DEBUG);
}
}
NetworkListener.java (服务器端)
package com.azsde.Chatty;
//All my imports
public class ChattyServer {
//Mes objets
private Server server;
private ArrayList <Clients> clientsList;
//Mes méthodes
//Constructeur
public ChattyServer() throws IOException
{
clientsList = new ArrayList <Clients>();
server = new Server();
registerPackets();
server.addListener(new NetworkListener(clientsList));
server.bind(101);
server.start();
// Open a window to provide an easy way to stop the server.
JFrame frame = new JFrame("Chatty Server");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.addWindowListener(new WindowAdapter()
{
public void windowClosed (WindowEvent evt)
{
server.stop();
}
});
frame.getContentPane().add(new JLabel("Close to stop the server."));
JPanel panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.SOUTH);
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
listClients();
}
});
panel.add(btnNewButton);
frame.setSize(320, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void registerPackets()
{
Kryo kryo = server.getKryo();
kryo.register(Packet0ConnectionRequest.class);
kryo.register(Packet1RequestResponse.class);
kryo.register(Packet2Message.class);
kryo.register(Packet3Order.class);
}
private void listClients()
{
for (int i = 0 ; i < clientsList.size() ; i ++)
{
if (!clientsList.isEmpty())
{
System.out.println(clientsList.get(i).getUsername());
System.out.println(clientsList.get(i).getIpAdress());
}
}
}
public static void main (String[] args)
{
try {
new ChattyServer();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.set(Log.LEVEL_DEBUG);
}
}
Packet.java (服务器和客户端通用)
package com.azsde.Chatty;
public class Packet {
public static class Packet0ConnectionRequest {String username;}
public static class Packet1RequestResponse {Boolean accepted = false;}
public static class Packet2Message {String message;}
public static class Packet3Order {Boolean start = false;}
}
ChattyClient.java
package com.azsde.Chatty;
//My imports
public class ChattyClient {
public Client client;
public static Scanner scanner;
public ChattyClient()
{
scanner = new Scanner(System.in);
client = new Client();
register();
NetworkListener nl = new NetworkListener();
nl.init(client);
client.addListener(nl);
client.start();
client.setKeepAliveTCP(50);
try
{
client.connect(50000, "127.0.0.1", 101);
}
catch (IOException e)
{
e.printStackTrace();
client.close();
}
}
private void register()
{
Kryo kryo = client.getKryo();
kryo.register(Packet0ConnectionRequest.class);
kryo.register(Packet1RequestResponse.class);
kryo.register(Packet2Message.class);
kryo.register(Packet3Order.class);
}
public static void main (String[] args)
{
new ChattyClient();
Log.set(Log.LEVEL_DEBUG);
}
}
NetworkListener.java (客户端)
package com.azsde.Chatty;
//My imports
public class NetworkListener extends Listener
{
private Client client;
public void init(Client client)
{
this.client = client;
}
public void connected(Connection arg0)
{
Packet0ConnectionRequest conRequest = new Packet0ConnectionRequest();
conRequest.username = System.getProperty("user.name");
Log.info("[CLIENT] You have connected");
client.sendTCP(conRequest);
}
public void disconnected(Connection arg0)
{
Log.info("[CLIENT] You have disconnected.");
}
public void received(Connection c, Object o)
{
if ( o instanceof Packet1RequestResponse)
{
Log.info("I got a response");
if (((Packet1RequestResponse) o).accepted)
{
Log.info("[CLIENT] You have connected.");
while(true)
{
if (ChattyClient.scanner.hasNext())
{
Log.info("Enter your message : ");
Packet2Message mpacket = new Packet2Message();
mpacket.message = ChattyClient.scanner.nextLine();
client.sendTCP(mpacket);
}
}
}
else
{
Log.info("[CLIENT] Connection failed.");
c.close();
}
}
if ( o instanceof Packet3Order)
{
Log.info("I got an order");
if (((Packet3Order) o).start) Log.info("Start");
else Log.info("Stop");
}
}
}
有人可以告诉我我做错了什么吗?即使客户端已经闲置了很长时间,我也希望客户端和服务器之间保持连接。
提前谢谢!
答案 0 :(得分:0)
消息传递系统可根据需要设置/部署连接一次,或者设置/维护连接并使用流控制对象(也称为KeepAlive消息)提供通道(其中还可能包含有关连接或客户端/服务器端状态的遥测详细信息)等)。
因此,根据您的任务定义(保持连接)和(避免空闲状态下的T / O),最简单的解决方案是:
完成此操作后,您可以根据自己的意愿或在消息传递体系结构需求增长时,将更多逻辑添加到此类简单的信令/控制层中。
答案 1 :(得分:0)
我做了一些非常愚蠢的事。
拥有:mpacket.message = ChattyClient.scanner.nextLine();
使我的程序等待输入,因此,在此期间,没有keepAlive数据包被发送到服务器。