论坛首页 Java版

socet短信发送与线程设计的问题

浏览 2719 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
最后更新时间:2007-09-14
没用过小灵通的,移动的企业短信通服务,发送和接收反馈是异步的,用一个MsgId可以对应,根本不需要LZ这么复杂。建议LZ是不是看看小灵通短信的文档有没有类似的MsgId可以关联
   
0 请登录后投票
最后更新时间:2007-09-16
hankesi2000 写道
线程池应该是少不了的,不过在子线程里等待反馈结果,这无疑会一直占用着内存,如果在网络不好或其他情况导致发送信息不通过,可能就会导致阻塞。
认为最好有收和发的2个主线程,这样运作能好一些!

这就要看协议了,一般协议都会有规定超时时间,即使协议没有规定,编程的时候也需要考虑到这个问题,这是编程水平问题.
收和发两个线程?他发和收是同步的,怎么用两个线程?
   
0 请登录后投票
最后更新时间:2007-09-16
每次new socket肯定是不现实的,用一个socket就够了,速度足够快。
尽量把发送和接收分别放在两个线程中。

建立两个BlockingQueue:
1. 可由多个线程生成要发送的内容,然后将这些内容放到一个BlockingQueue中,发送线程重queue中获得内容,然后通过socket发送出去。
2. 接收线程只负责接收数据,收到的数据放到一个接收的BlockingQueue中,后面n多个线程从接收的queue中获得要出来的内容,然后处理,例如写数据库。

另外:out.println("<FROM:10060><TO:" + called_num + "><MSG: DY " + info + ">\r\n");
格式有问题,如果info有\r\n就麻烦大了,要自己做encode的过程,对info中的">"这类字符转码。

socket通信常见个格式是:包的长度 + 包的内容。而不是用\r\n来表示包结束。
   
0 请登录后投票
最后更新时间:2007-09-17
同意楼上的管理,采用异步的方式进行工作。
  发送端采用一个线程池,起线程只管发socket。
  接收端起一个线程池,接受socket,处理完后,放入一个处理结果  队列。起一个线程专门读这个操作结果。
  如果要重发,直接起线程发就是了。
   
0 请登录后投票
最后更新时间:2007-09-18
我的理解是,楼主要开发的是一个web应用,它接受客户端请求然后转发给短信服务器,
因此这个web应用本身是一个短信服务器的客户端

其实,socket服务器的客户端跟数据库的客户端没有本质区别,
因此这里不需要考虑线程池问题,servlet程序本身就是多线程的,
只要写个servlet,每个请求进来后发起一个socket连接即可

至于处理时间较长的问题,也只是阻塞相应地socket本身,不影响处理其他请求
   
0 请登录后投票
最后更新时间:2007-09-18
用nio加队列,不要搞什么并发了,费神,容易出错
   
0 请登录后投票
最后更新时间:2007-09-20
用长连接及异步。你每发个消息都要创建个socket!并且还要做群发?消息量大了怎么办?smgp协议每个消息都有序列号(SequenceID)。分别建立收、发线程,就行了。写个消息队列。对上层,往这队列加消息。对下发送线程只负责从队列中取出消息发到网络。
   
0 请登录后投票
最后更新时间:2007-09-21
daquan198163 写道
我的理解是,楼主要开发的是一个web应用,它接受客户端请求然后转发给短信服务器,
因此这个web应用本身是一个短信服务器的客户端

其实,socket服务器的客户端跟数据库的客户端没有本质区别,
因此这里不需要考虑线程池问题,servlet程序本身就是多线程的,
只要写个servlet,每个请求进来后发起一个socket连接即可

至于处理时间较长的问题,也只是阻塞相应地socket本身,不影响处理其他请求


支持!

楼主的问题可能是这样的:
在网页上填写消息内容、接收人(多个),提交到servlet,servlet发送短信,发送完成后在页面显示结果。

全部发送成功或重试n次都不成功后返回发送结果。

如果RP不好,要重试很多次,导致界面N久才有信息显示。


现在想改成这样:
servlet把短信交给多个线程发送,servlet本身立即返回。

发送短信的线程把发送结果(给****发送成功,给****发送失误)写入数据库,假设是表是x,页面不停刷新去读表x,及时显示发送情况。发送情况还可以显示这种情形:给****发送失误,正在进行第n次尝试。

如果是如上所述,下面是简单的实现代码
MsgSender implements Runnable {
	private boolean stop = false;
	private LinkedList queue;

	public MsgSender(LinkedList queue) { 
		this.queue = queue;
	}

	public void run() {
		while(true) {
			Msg msg = null;
			synchronized(queue) {
				while(!stop && queue.isEmpty())
					queue.wait();  //没有,等吧

				if(stop) //等到了stop信号
					break;

				msg = (Msg) queue.removeFirst();  //一定要在同步块里面读取Msg
			}

			//取到了msg才会到这里
			if(! sendMsg(msg)) {
				synchronized(queue) {
					queue.addLast(msg);
					queue.notify();
				}
			}
		}
	}

	public boolean sendMsg(Msg msg) {
		...
	}

	public void stop() {
		this.stop = true;
	}
}

SendMsgServlet extends HttpServlet {
	private LinkedList queue = new LinkedList();
	private List<MsgSender> senders = new ArrayList<MsgSender>();
	public void init() {
		int threadCount = 10; //TODO: 在web.xml中配置
		for(int i=0; i<threadCount; i++) {
			MsgSender sender = new MsgSender(queue);
			senders.add(sender);
			new Thread(sender).start();
		}
	}

	public void destroy() {
		for(MsgSender sender : senders) {
			sender.stop();
		}
		queue.notifyAll();
	}

	public void service(HttpServletRequest request, HttpServletResponse response) {
		Msg msg = null;
		... //从request创建Msg
		synchronized(queue) {
			queue.addLast(msg);
			queue.notify();
		}
	}
}
   
0 请登录后投票
最后更新时间:2007-09-21
用长连接要看短信平台是否支持。楼主所要连接的短信平台很有可能是不支持长连接的。

并且不支持异步返回信息,因为如果是异步的,必须要传递一个msgId。
   
0 请登录后投票
论坛首页 Java版

跳转论坛:
JavaEye推荐