首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

创建基于 Ajax 的 IM 客户端(8)处理 roster 更新

创建基于 Ajax 的 IM 客户端(8)处理 roster 更新

显示 rosterPrototype 使得向页面添加 roster 变得异常简单(参见清单 25):
清单 25. 显示 roster
1
2
3
4
5
6
7
....
function populateForm(){
   new Ajax.Updater('roster', 'ChatServlet', {
     method: 'get',
     parameters: {getRoster: 'yes'}
   });
....




在填充页面时,请采取额外步骤调用此 servlet 以便获取 roster 并用它来更新 roster div。如前所述,getRoster 的值并不重要。如果保存和编译所有合适的文件并重启 servlet 引擎以期获得全新的 bot 实例,roster 就会出现在右侧 div,如图 10 所示:
图 10. roster但我们还有一个问题:我们没有现成的 Chat 对象给这些人。
为 roster 发起对话要与某人对话,需要先有 Chat 对象。在 ChatBot,这发生于 createConversation() 方法,意味着需要为 roster 中的每个条目都要调用它(参见清单 26):
清单 26. 创建对话
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
....
    public void startNew(){

        try{
            conn = new XMPPConnection("myserver.net");
            conn.connect();
            conn.login("myprimaryaccount", "mypassword");

            Roster roster = conn.getRoster();
            Iterator<RosterEntry> iter =
                       roster.getEntries().iterator();
            while (iter.hasNext()) {
                RosterEntry entry = (RosterEntry) iter.next();
                createConversation(entry.getUser());
            }


        } catch (Exception e){
            System.out.println("StartNew Exception");
            e.printStackTrace();
        }

        System.out.println("Done.");
    }
}




在首次实例化 servlet 内的 bot 时,都要调用 startNew() ,所以这是很好的一个运行 roster 内的每个条目并为其创建对话的地方。这也是发起原始对话的地方,所以变化不是很大。
选择新用户:向 roster 添加脚本即使在 roster 上有了这些用户,如果没有办法告知 Web 客户端您想要与之交谈,用处也不会很大。要实现此目的,需要让页面在您单击用户名字的时候,能够切换到新用户。
实现这个目的的方法很多,包括将 roster 作为数组传递并动态地将每一个都添加到此文档或使用 Ajax 框架创建一个选项卡系统。在很多时候,越简单越好。
编辑 ChatBot 类以便向每个 roster 条目都添加事件处理程序(参见清单 27):
清单 27. 每个 roster 条目都添加事件处理程序
1
2
3
4
5
6
7
8
9
10
11
12
13
....
    public String getRoster(){
        Roster roster = conn.getRoster();
        String returnStr = "";
        Iterator<RosterEntry> iter = roster.getEntries().iterator();
        while (iter.hasNext()) {
            RosterEntry entry = (RosterEntry) iter.next();
            returnStr = returnStr + "<span id='"+entry.getUser()+
                   "' onclick='changeUser(\""+entry.getUser()+
                   "\", \""+entry.getName()+"\")'>"+entry.getName() +
                   "</span><br />";
        }
....




上述代码看上去不太整齐,如果佐以 HTML,结果应该如清单 28 所示:
清单 28. 结果 HTML
1
2
3
4
<span id='myfriend@myserver.net'
           onclick='changeUser("myfriend@myserver.net", "My Friend")'>
  My Friend
</span><br />




这里最重要的地方是 onclick 处理程序,它调用 changeUser() 函数,向它发送帐号和想要使用的显示名称。
现在,必须要在 Web 页面创建 changeUser() 函数。
选择新用户:更改 Web 页面现在可以开始最后一阶段的操作了。所需做的就是在单击 roster 内的名字时更改 “活动” 用户(参见清单 29):
清单 29. 更改用户
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
....
<script type="text/javascript">

var targetName = "Dafyd Llewellyn";
var targetUser = "myfriend@myserver.net";

var updater;

function changeUser(newUser, newName){
   $('currentChat').value = "";
   targetName = newName;
   targetUser = newUser;

   $('nameTag').innerHTML = targetName;

   updater.stop();
   updater = new Ajax.PeriodicalUpdater('currentChat', 'ChatServlet',
     {
       method: 'get',
       insertion: Insertion.Bottom,
       frequency: 3,
       parameters: {getMessages: targetUser}
     });
   
}


function populateForm(){
   new Ajax.Updater('roster', 'ChatServlet', {
     method: 'get',
     parameters: {getRoster: 'yes'}
   });

   updater = new Ajax.PeriodicalUpdater('currentChat', 'ChatServlet',
     {
       method: 'get',
       insertion: Insertion.Bottom,
....




这里发生了几件事情,让我们从底部开始。首先,PeriodicalUpdater 为当前用户重复请求队列。如果打算更改此用户,就需要告知 PeriodicalUpdater 停止 ping 旧地址,方法是创建一个全局 updater 变量并 将其设置为新对象。然后,再向上看,在 changeUser() 函数,使用 updater 变量调用 PeriodicalUpdater 的 stop() 方法,之后用正确的信息创建一个新用户。
最后,需要清除当前聊天,将 targetUsertargetName 变量设为合适的值并将 nameTag div 更改为新名称。
若要测试,可以刷新页面并在各种 roster 条目上单击。能否看到 IM 客户端上的动作取决于您与之登录的用户是否是页面的当前用户。
返回列表