论坛首页 移动开发技术论坛

用androidpn来实现推送

浏览 218266 次
精华帖 (0) :: 良好帖 (4) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-04-16  
zsg88 写道
花了一个下午的时间把后台修改成spring + hibernate + struts2 + tomcat能正常地跑起来了,经测试和手机连接正常发消息没有问题。

我现在正在做这个推送的,我是初学者,能把源码发给我研究一下吗?
我的邮箱是874655299@qq.com
不管发不发,先谢拉。兄弟!
0 请登录后投票
   发表时间:2012-04-16   最后修改:2012-04-16
cdztop 写道
2、假如我现在要实现的效果是这样的:一个用户只需要一个帐号(username,password),只有一台PushServer服务器,但是有很多需要push功能的Android应用,然后push的条件的username+对应的客户端应用。
我的想法是:xmpp里面有<node@domain/home>和<node@domain/work>,我想domain就是PushServer,home和work就是Android客户端的应用名,node就是帐号的username。我也试着测试了一下。但是有一个问题。
在session里面的列表是正常的,就是有两个名为username的session,但是users列表的对应user都是离线的,服务器广播出来的信息都收不到。
我想是SessionManager里面的public ClientSession getSession(String username)这个方法的问题。
它原来是:   
private static final String RESOURCE_NAME = "AndroidpnClient";
public ClientSession getSession(String username) {
    return getSession(new JID(username, serverName, RESOURCE_NAME, true));
}
这个RESOURCE_NAME就是我上面说的home和work的意思。
不知道你有没有明白我的意思。

总之就是一个username怎么才能有2个RESOURCE_NAME。而且能根据RESOURCE_NAME和username唯一确定一个ClientSession。




我的ssh版本,

在同一手机上运行2个客户端RESOURCE_NAME分别为AndroidpnClient和AndroidpnClient2

session.do页面显示2个在线,user.do页面显示一个在线。

打开UserController类,可以看到判断user是否在线的方法是presenceManager.isAvailable(user)

最终调用的是SessionManager

    public ClientSession getSession(String username) {
        // return getSession(new JID(username, serverName, null, true));
        return getSession(new JID(username, serverName, RESOURCE_NAME, true));
    }

注意:new JID(username, serverName, RESOURCE_NAME, true) 只指定了一个RESOURCE_NAME,表示只查找名称为RESOURCE_NAME所代表的应用用户,所以另外一个应用的用户就查找不到了。

把当前这行注释掉

把被注释的上一行打开,return getSession(new JID(username, serverName, null, true))
这里RESOURCE_NAME被设定为null,不指定具体应用名称

修改
public ClientSession getSession(JID from){
   ......
   //if (from.getResource() == null || from.getNode() == null) {
   //      return null;
   //}
      
   if (from.getResource() == null) {
      if (from.getNode() != null) {
for (ClientSession session : clientSessions.values()) {
   if (session.getAddress().getNode().equals(from.getNode())) {
      return session;
   }
}
      } else {
        return null;
      }
    }
     
    return clientSessions.get(from.toString());
}

重起运行,见图,附件

图太大了,点开看

第一张是 session列表
第二张是 user列表
  • 大小: 28.8 KB
  • 大小: 13.3 KB
0 请登录后投票
   发表时间:2012-04-16  
shiwenbin770 写道
zsg88 写道
花了一个下午的时间把后台修改成spring + hibernate + struts2 + tomcat能正常地跑起来了,经测试和手机连接正常发消息没有问题。

我现在正在做这个推送的,我是初学者,能把源码发给我研究一下吗?
我的邮箱是874655299@qq.com
不管发不发,先谢拉。兄弟!


已发
0 请登录后投票
   发表时间:2012-04-16  
zsg88 写道
shiwenbin770 写道
zsg88 写道
花了一个下午的时间把后台修改成spring + hibernate + struts2 + tomcat能正常地跑起来了,经测试和手机连接正常发消息没有问题。

我现在正在做这个推送的,我是初学者,能把源码发给我研究一下吗?
我的邮箱是874655299@qq.com
不管发不发,先谢拉。兄弟!


已发

收到了。哥。。。太感谢了。明儿个好好研究一下
0 请登录后投票
   发表时间:2012-04-16  
zsg88 写道
在同一手机上运行2个客户端RESOURCE_NAME分别为AndroidpnClient和AndroidpnClient2
session.do页面显示2个在线,user.do页面显示一个在线。
打开UserController类,可以看到判断user是否在线的方法是presenceManager.isAvailable(user)
最终调用的是SessionManager
    public ClientSession getSession(String username) {
        // return getSession(new JID(username, serverName, null, true));
        return getSession(new JID(username, serverName, RESOURCE_NAME, true));
    }
注意:new JID(username, serverName, RESOURCE_NAME, true) 只指定了一个RESOURCE_NAME,表示只查找名称为RESOURCE_NAME所代表的应用用户,所以另外一个应用的用户就查找不到了。
把当前这行注释掉
把被注释的上一行打开,return getSession(new JID(username, serverName, null, true))
这里RESOURCE_NAME被设定为null,不指定具体应用名称
修改
public ClientSession getSession(JID from){
   ......
   //if (from.getResource() == null || from.getNode() == null) {
   //      return null;
   //}
      
   if (from.getResource() == null) {
      if (from.getNode() != null) {
for (ClientSession session : clientSessions.values()) {
   if (session.getAddress().getNode().equals(from.getNode())) {
      return session;
   }
}
      } else {
        return null;
      }
    }
    return clientSessions.get(from.toString());
}


非常感谢,你说的我测试了,如果广播信息的话,两个都可以收到。但是如果指定username发送的话,只有一个可以收到。我看了一下代码,还应该修改NotificationManager里面的
public void sendNotifcationToUser(String apiKey, String username,
String title, String message, String uri, String time) {
log.debug("sendNotifcationToUser()...");
IQ notificationIQ = createNotificationIQ(apiKey, title, message, uri,
time);
ClientSession session = sessionManager.getSession(username);
if (session != null) {
if (session.getPresence().isAvailable()) {
notificationIQ.setTo(session.getAddress());
session.deliver(notificationIQ);
}
}
}

把这个方法改成下面的就可以了。
public void sendNotifcationToUser(String apiKey, String username,
String title, String message, String uri, String time)
throws UserNotFoundException {
log.debug("sendNotifcationToUser()...");
IQ notificationIQ = createNotificationIQ(apiKey, title, message, uri,
time);
for (ClientSession session : sessionManager.getSessions()) {
if (session.getUsername().equals(username)
&& session.getPresence().isAvailable()) {
notificationIQ.setTo(session.getAddress());
session.deliver(notificationIQ);
}
}
}

0 请登录后投票
   发表时间:2012-04-16   最后修改:2012-04-16
zsg88 写道
在同一手机上运行2个客户端RESOURCE_NAME分别为AndroidpnClient和AndroidpnClient2
session.do页面显示2个在线,user.do页面显示一个在线。


还有两个问题。
1、情景是这样的:一个手机里面有多个客户端需要push服务,但是只有一个用户名,现在已经可以实现了。但是这种方式应该客户有多少个,后台的service就有多少个吧?能不能多个客户端公用一个service,第一个客户端启动后,就启动service,最后一个客户端关闭后才关闭service,service收到信息后再根据resource来决定要推给那个客户端?

2、如果手机1安装客户端1用username1登录后为session1,手机2安装客户端1用username1登录后为session2,这个session2只是session1的created time更新了,其他的不变,但是这个时候只有session2可以接收到信息,但是手机1没有收到任何提示信息,然而它永远也不能收到信息了。而且如果这个时候session1退出service的话,那么session2也关闭了,但是手机2的客户端还开着,然而它永远也连不上服务器了。我想当出现这种情况的时候给手机1一个提示信息,表示你的帐号在别处登录了。
0 请登录后投票
   发表时间:2012-04-16  
cdztop 写道
zsg88 写道
在同一手机上运行2个客户端RESOURCE_NAME分别为AndroidpnClient和AndroidpnClient2
session.do页面显示2个在线,user.do页面显示一个在线。


还有一个问题。情景是这样的:一个手机里面有多个客户端需要push服务,但是只有一个用户名,现在已经可以实现了。但是这种方式应该客户有多少个,后台的service就有多少个吧?能不能多个客户端公用一个service,第一个客户端启动后,就启动service,最后一个客户端关闭后才关闭service,service收到信息后再根据resource来决定要推给那个客户端?



远程服务(Remote Sercie):

0 请登录后投票
   发表时间:2012-04-16  
cdztop 写道
zsg88 写道
在同一手机上运行2个客户端RESOURCE_NAME分别为AndroidpnClient和AndroidpnClient2
session.do页面显示2个在线,user.do页面显示一个在线。


还有两个问题。
1、情景是这样的:一个手机里面有多个客户端需要push服务,但是只有一个用户名,现在已经可以实现了。但是这种方式应该客户有多少个,后台的service就有多少个吧?能不能多个客户端公用一个service,第一个客户端启动后,就启动service,最后一个客户端关闭后才关闭service,service收到信息后再根据resource来决定要推给那个客户端?

2、如果手机1安装客户端1用username1登录后为session1,手机2安装客户端1用username1登录后为session2,这个session2只是session1的created time更新了,其他的不变,但是这个时候只有session2可以接收到信息,但是手机1没有收到任何提示信息,然而它永远也不能收到信息了。而且如果这个时候session1退出service的话,那么session2也关闭了,但是手机2的客户端还开着,然而它永远也连不上服务器了。我想当出现这种情况的时候给手机1一个提示信息,表示你的帐号在别处登录了。


1、先仔细看看MINA框架,本来就是多个客户端公用一个service,但是是有数量限制的。。
2、这个也可以解决的,在用户登录的时候,去session里轮询下是否已经有登录的,有的话就把登录的退出。不难解决,关键还是要理清服务端的流程。
0 请登录后投票
   发表时间:2012-04-17  
zsg88 写道
花了一个下午的时间把后台修改成spring + hibernate + struts2 + tomcat能正常地跑起来了,经测试和手机连接正常发消息没有问题。


这发个贴太不容易了,我也求开源,邮箱duanxiaoni006@163.com,不知会不会被删哟,谢楼主
0 请登录后投票
   发表时间:2012-04-17  
xalydxn 写道
zsg88 写道
花了一个下午的时间把后台修改成spring + hibernate + struts2 + tomcat能正常地跑起来了,经测试和手机连接正常发消息没有问题。


这发个贴太不容易了,我也求开源,邮箱duanxiaoni006@163.com,不知会不会被删哟,谢楼主

收到,无限感激中...
0 请登录后投票
论坛首页 移动开发技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics