当前位置:编程学习 > JAVA >>

java socket 长连接奇怪的问题

我有一个类,负责通过SOCKET长连接与服务器端通讯。
这个循环读取一个队列来发送。
问题来了,在本类的MAIN方法中向队列中添加数据,就可以发送出去,在SERVLET中,通过HTTP请求添加,就是发送不出去!请大家帮忙看看,谢谢。下面是这个主要类的代码。

/**
 * 
 */
package com.dianshangwang.lianhepayfront.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;

import com.dianshangwang.lianhepayfront.global.Config;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

/**
 * @author lay
 * @date 2013年11月4日
 */
public class IcardpayClient {
private static Logger log = Logger.getLogger(IcardpayClient.class);

private static Socket socket;
private static BufferedReader reader;
private static PrintWriter writer;
private static Thread sendThread;
private static Thread receiveThread;
private static Thread monitorThread;

private static boolean isRunning = false;

/**
 * 心跳计数器 若此值与当前时间戳值小于60000则认定断线,进行重联操作
 */
private static Long heartbeatTimestamp = System.currentTimeMillis();

private static IcardpayClient instance = new IcardpayClient();

private IcardpayClient() {
}

public static IcardpayClient getInstance() {
return instance;
}

public static void main(String[] args) {
BasicConfigurator.configure();
IcardpayClient client = new IcardpayClient();
client.start();

MsgQueue.sendQueue.add("{\"agentNo\":\"A10342hp\",\"tradeType\":\"256\",\"sessionId\":\"1\"}");
}

public void start() {
init();

sendThread = new Thread(new SendThread());// 启动读线程
receiveThread = new Thread(new ReceiveThread());// 启动收线程
monitorThread = new Thread(new MonitorThread()); // 启动监视线程

sendThread.setName("icardpay-send-thread");
receiveThread.setName("icardpay-receive-thread");
monitorThread.setName("icardpay-monitor-thread");

// sendThread.setDaemon(true);
// receiveThread.setDaemon(true);
// monitorThread.setDaemon(true);

sendThread.start();
log.info("SOCKET发送线程开启!");
receiveThread.start();
log.info("SOCKET接收线程开启!");
// monitorThread.start();
// log.info("SOCKET监视线程开启!");

}

public void restart() {
stop();
init();
}

public void stop() {
isRunning = false;
}

private void init() {
socket = new Socket();
try {
socket.setKeepAlive(true);
socket.connect(new InetSocketAddress(Config.icardpayHost, Config.icardpayPort));
reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
writer = new PrintWriter(socket.getOutputStream());

heartbeatTimestamp = System.currentTimeMillis();

log.info("已创建与支付通的SOCKET连接!");

isRunning = true;
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public void write(String msg) {
writer.println(msg);
writer.flush();
log.info(Thread.currentThread().getName() + "发送:" + msg);
}

private String read() throws IOException {
String msg = reader.readLine();
if (msg != null) {
log.info("接收:" + msg);
}
return msg;
}

class SendThread implements Runnable {

@Override
public void run() {

while (isRunning) {

if (!MsgQueue.sendQueue.isEmpty()) {

String v = MsgQueue.sendQueue.poll();

write(v);
}

try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}

}

class ReceiveThread implements Runnable {

@Override
public void run() {
while (isRunning) {

String content = null;
try {
content = read();
} catch (IOException e1) {
log.error("SOCKET读取异常,将重新启动。。。", e1);
restart();
continue;
}

if (null == content || content == "") {
continue;
}

JsonObject obj = new JsonParser().parse(content).getAsJsonObject();

if (obj.has("tradeType") && "0".equals(obj.get("tradeType").getAsString())) {
// 收到心跳包, 刷新计数器
heartbeatTimestamp = System.currentTimeMillis();
continue;
}

if (!obj.has("sessionId")) {
log.info("收到未标识的包:" + obj.toString());
continue;
}

String id = obj.get("sessionId").getAsString();

if (MsgQueue.listeners.containsKey(id)) {
MsgQueue.listeners.get(id).received(content);
MsgQueue.listeners.remove(id);
} else {
log.info("接收到过期包:" + content);
}

try {
Thread.sleep(100);
} catch (InterruptedException e) {
// 忽略
}

}
}

}

class MonitorThread implements Runnable {

String heartbeat = "{\"agentNo\":\"A10342hp\",\"tradeType\":\"0\"}";

@Override
public void run() {
while (isRunning) {
if (System.currentTimeMillis() - heartbeatTimestamp >= 60000) {
// SOCKET已失效
restart();
}

// 发送心跳包
write(heartbeat);

try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// 忽略
}
}
}

}
}
java socket 长连接 --------------------编程问答--------------------  , socket 没用过 ,只用过mina 。mina已经在封装好了 socket ,所以还是挺好的 。个人感觉这个框架够用 。 --------------------编程问答-------------------- 有没有报错啊 发出来看看 --------------------编程问答-------------------- 是不是会抛异常;IOException?
补充:Java ,  Java EE
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,