|
锁定老贴子 主题:socet短信发送与线程设计的问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
最后更新时间:2007-09-14
没用过小灵通的,移动的企业短信通服务,发送和接收反馈是异步的,用一个MsgId可以对应,根本不需要LZ这么复杂。建议LZ是不是看看小灵通短信的文档有没有类似的MsgId可以关联
|
|
| 返回顶楼 | |
|
最后更新时间:2007-09-16
hankesi2000 写道 线程池应该是少不了的,不过在子线程里等待反馈结果,这无疑会一直占用着内存,如果在网络不好或其他情况导致发送信息不通过,可能就会导致阻塞。
认为最好有收和发的2个主线程,这样运作能好一些! 这就要看协议了,一般协议都会有规定超时时间,即使协议没有规定,编程的时候也需要考虑到这个问题,这是编程水平问题. 收和发两个线程?他发和收是同步的,怎么用两个线程? |
|
| 返回顶楼 | |
|
最后更新时间: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来表示包结束。 |
|
| 返回顶楼 | |
|
最后更新时间:2007-09-17
同意楼上的管理,采用异步的方式进行工作。
发送端采用一个线程池,起线程只管发socket。 接收端起一个线程池,接受socket,处理完后,放入一个处理结果 队列。起一个线程专门读这个操作结果。 如果要重发,直接起线程发就是了。 |
|
| 返回顶楼 | |
|
最后更新时间:2007-09-18
我的理解是,楼主要开发的是一个web应用,它接受客户端请求然后转发给短信服务器,
因此这个web应用本身是一个短信服务器的客户端 其实,socket服务器的客户端跟数据库的客户端没有本质区别, 因此这里不需要考虑线程池问题,servlet程序本身就是多线程的, 只要写个servlet,每个请求进来后发起一个socket连接即可 至于处理时间较长的问题,也只是阻塞相应地socket本身,不影响处理其他请求 |
|
| 返回顶楼 | |
|
最后更新时间:2007-09-18
用nio加队列,不要搞什么并发了,费神,容易出错
|
|
| 返回顶楼 | |
|
最后更新时间:2007-09-20
用长连接及异步。你每发个消息都要创建个socket!并且还要做群发?消息量大了怎么办?smgp协议每个消息都有序列号(SequenceID)。分别建立收、发线程,就行了。写个消息队列。对上层,往这队列加消息。对下发送线程只负责从队列中取出消息发到网络。
|
|
| 返回顶楼 | |
|
最后更新时间: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();
}
}
}
|
|
| 返回顶楼 | |
|
最后更新时间:2007-09-21
用长连接要看短信平台是否支持。楼主所要连接的短信平台很有可能是不支持长连接的。
并且不支持异步返回信息,因为如果是异步的,必须要传递一个msgId。 |
|
| 返回顶楼 | |








