国外聊天室

更新时间:2022-12-28 15:22:29 阅读: 评论:0


2022年12月28日发(作者:如何祛斑美白)

XMPP协议简介

XMPP协议(ExtensibleMessagingandPrenceProtocol,可扩展消息处理现场协议)

是一种基于XML的协议,目的是为了解决及时通信标准而提出来的,最早是在Jabber上

实现的。它继承了在XML环境中灵活的发展性。因此,基于XMPP的应用具有超强的可扩

展性。并且XML很易穿过防火墙,所以用XMPP构建的应用不易受到防火墙的阻碍。利用

XMPP作为通用的传输机制,不同组织内的不同应用都可以进行有效的通信。

这篇文章有基本的介绍,

/xutaozero21/article/details/4873439

IM

InstantMesnger,及时通信软件,就是大家使用的QQ、MSNMesnger和Gtalk

等等。其中Gtalk就是基于XMPP协议的一个实现,其他的则不是。当前IM几乎作为每

个上网者必然使用的工具,在国外的大型企业中有一些企业级的IM应用,但是其商业价值

还没完全发挥出来。设想既然XMPP协议是一个公开的协议,那么每个企业都可以利用它

来开发适合本身企业工作,提高自身生产效率的IM;甚至,你还可以在网络游戏中集成这

种通信软件,不但让你可以边游戏边聊天,也可以开发出适合游戏本身的IM应用,比如说

一些游戏关键场景提醒功能,团队语音交流等等都可以基于IM来实现。

本文主要讲解在android使用xmpp协议进行即时通信,所涉及3个主要的东西,它们是

openfire、smack和spark,这个三个东东结合起来就是完整的xmppIM实现,这里简

单介绍一下这3个东东在下文的作用:

openfire主要是作为服务器,负责管理客户端的通信连接,以及提供客户端一些通信信息

和连接信息。

Smack主要是xmpp协议的实现,提供了一套很好的api,所以下面操作xmpp都是通过

使用smack的api来实现,当然因为是在android里,所以使用的是asmack这个包,

里面方法跟smack包差不多。

Spark是IM客户端的实现,其实就是使用了smack的api实现的。

下图展示了三者之间的关系:(很明显这个图是偷别人的,具体是哪里我忘了,因为资料都

是复制到文档后慢慢研究看的)

从图上可以了解到,client端和rver端都可以通过插件的方式来进行扩展,smack是

二者传递数据的媒介。

配置openfire服务器

具体步骤请移步:

/blog/static/87/

配置成功如果以后ip地址变了,那肯定又是开不了,解决办法请移步:

/HappySheepherder/article/details/4707124

配置成功后,在服务器创建一个简单的用户来测试,然后安装spark,设置好服务器的ip

与端口,使用刚才创建的用户登录,登录OK说明服务器成功搭建。

AndroidIM功能(因为是测试demo,因此界面超级简陋,代码都是给出重要的一部分,

剩余的可以在最后下面项目查看)

配置要求

android2.2、、myeclip

连接服务器

在打开软件后会开始初始化,完成与openfire服务器的连接,设置一些配置

static{

_ENABLED=true;

finalConnectionConfigurationconnectionConfig=new

ConnectionConfiguration(

host,5222,"");

//Googletalk

//ConnectionConfigurationconnectionConfig=

new

//ConnectionConfiguration(

//"",5222,"");

//

LAuthenticationEnabled(fal);

tion=new

XMPPConnection(connectionConfig);

_ENABLED=true;

ProviderManagerpm=tance();

configure(pm);

}

注册模块

注册有两种方法:一种是用createAccount,不过我测试了一下发现不能创建用户,具体

原因不详,下面介绍第二种。

如上图:注册成功后服务器将多了ggg用户。

具体实现如下:

Registrationreg=newRegistration();

e();

(tance().getService

Name());

rname(t().toString());

sword(t().toString());

ribute("android",

"geolo_createUr_android");

n("reg:"+reg);

PacketFilterfilter=newAndFilter(newPacketIDFilter(reg

.getPacketID()),new

PacketTypeFilter());

PacketCollectorcollector=

tance()

.createPacketCollector(filter);

tance().ndPacket(reg);

result=(IQ)sult(SmackConfiguration

.getPacketReplyTimeout());

//Stopqueuingresults

();

if(result==null){

xt(getApplicationContext(),"服,

_SHORT).show();

}elif(e()==

){

if(or().toString().equalsIgnoreCa(

"conflict(409)")){

xt(getApplicationContext(),"这,

_SHORT).show();

}el{

xt(getApplicationContext(),"注,

_SHORT).show();

}

}elif(e()==

){

xt(getApplicationContext(),"恭,

_SHORT).show();

}

使用注册类,设置好注册的用户名密码和一些属性字段,直接设置包过滤,根据这个过滤创

建一个结果集合,发送注册信息包,等待获取结果,剩余就是判断结果内容.

登录模块

登录比较简单

tance().connect();//connect

Stringaccount=t().toString();

Stringpassword=t().toString();

//保存用户和密码

ring(ACCOUNT_KEY,account);

ring(PASSWORD_KEY,

password);

tance().login(account,

password);//login

//loginsuccess

n("loginsuccess");

ntAccount=account;

n(tance()

.getUr());

//登录成功后发现在线状态

Prenceprence=new

Prence(ble);

tance().ndPacket(prence

);

//开始主界面

Intentintent=newIntent(,

);

startActivity(intent);

获取联系人模块(ActivityMain主界面)

获取联系人并将相关信息保存到一个list数组里,最后通知listview更新界面

roster=ter();

publicvoidupdateRoster(){

Collectionentries=

ries();

for(RosterEntryentry:entries){

(e()+"-"+

r()+"-"

+e()+"-"+

ups().size());

Prenceprence=

nce(r());

n("-"+tus()+"-

"

+m());

Urur=newUr();

e(e());

r(r());

e(e());

e(ups().size());

tus(tus());

m(m());

(ur);

}

DataSetChanged();

}

单人聊天模块

第一次修改:

在主界面点击选择一个用户,进入聊天Activity,ActivityChat先获取传过来的用户,创

建聊天类并对该用户设置消息监听

ChatManagerchatmanager=

tance()

.getChatManager();

//getur

Intentintent=getIntent();

Stringur=ingExtra("ur");

n("ur:"+ur);

//newassion

newChat=Chat(ur,null);

//监听聊天消息

tListener(new

ChatManagerListenerEx());

//ndmessage

try{

ssage("imbirdman");

}catch(XMPPExceptione){

//TODOAuto-generatedcatchblock

tackTrace();

}

监听类

publicclassChatManagerListenerEximplements

ChatManagerListener{

@Override

publicvoidchatCreated(Chatchat,booleanarg1){

//TODOAuto-generatedmethodstub

sageListener(ml);

}

}

publicclassMessageListenerEximplements

MessageListener{

@Override

publicvoidprocessMessage(Chatarg0,Message

message){

Stringresult=m()+":"+

y();

n(result);

emsg=e();

=0;

Bundlebd=newBundle();

ing("msg",result);

a(bd);

ssage(msg);

}

}

所获取到的消息都是通过handler来更新UI

publicHandlerhandler=newHandler(){

@Override

publicvoidhandleMessage(emsg){

switch(){

ca0:{

Stringresult=

a().getString("msg");

t(t()+"n"+result);

}

break;

default:

break;

}

}

};

aaa跟bbb的聊天

第二次修改:

第一次的测试,发现如果多个人之间都成为好友,那么他们之间的聊天就出现了接收不到的

信息,当然在跟spark测试时,spark可以收到android端的信息,不过android客户端

是收到这个信息,不过却没有显示出来,具体原因还不太清楚。因此在第二次修改我改成监

听所有聊天信息包,然后再分析包的归属,分发到对应的聊天窗口。

这里就是监听到包后打印的消息,打印出了jid和消息内容

publicclassXmppMessageManagerimplements

ChatManagerListener{

privateXMPPConnection_connection;

privateChatManagermanager=null;

publicvoidinitialize(XMPPConnectionconnection){

_connection=connection;

manager=_tManager();

tListener(this);

}

@Override

publicvoidchatCreated(Chatchat,booleanarg1){

//TODOAuto-generatedmethodstub

sageListener(newMessageListener(){

publicvoidprocessMessage(Chatnewchat,Message

message){

//若是聊天窗口存在,将消息转往目前窗口

//若窗口不存在,创建新的窗口

.println(m()

+":"+y());

if(!nsKey(m()))

{

(m(),newchat);

}el{

}

}

});

}

}

主要就是重写了ChatManagerListener类的监听,分发处理暂时没有想好怎么写。接着

在后台启动rvice就可以开始监听,行了第一次修改那些可以去掉了^0^。

多人聊天模块

也是在主界面的菜单进入ActivityMultiChat,该界面显示所创建的房间,点击就跳转到

ActivityMultiRoom。

获取所有房间比较简单,只需执行下面这段代码

hostrooms=tedRooms(tion,

"aitao-pc");

跳转到后获取要加入的房间的jid,并创建监听。

jid=getIntent().getStringExtra("jid");

//后面服务名称必需是创建房间的那个服务

StringmultiUrRoom=jid;

try{

muc=newMultiUrChat(tion,

multiUrRoom);

//创建聊天室,进入房间后的nickname

(ntAccount);

Log.v(TAG,"joinsuccess");

}catch(XMPPExceptione){

//TODOAuto-generatedcatchblock

tackTrace();

}

ChatPacketListenerchatListener=new

ChatPacketListener(muc);

sageListener(chatListener);

监听大概的流程跟单人聊天差不多,都是handler来操作。不过多人聊天是重写了

PacketListener。具体如下(不过该方法是监听房间的信息,也就是说显示的是以房间为

名字的消息):

classChatPacketListenerimplementsPacketListener{

privateString

_number;

privateDate

_lastDate;

privateMultiUs

erChat_muc;

privateString

_roomName;

publicChatPacketListener(MultiUrChatmuc){

_number="0";

_lastDate=newDate(0);

_muc=muc;

_roomName=m();

}

@Override

publicvoidprocessPacket(Packetpacket){

Messagemessage=(Message)packet;

Stringfrom=m();

if(y()!=null){

DelayInformationinf=(DelayInformation)

ension(

"x","jabber:x:delay");

DatentDate;

if(inf!=null){

ntDate=mp();

}el{

ntDate=newDate();

}

Log.w(TAG,"Receiveoldmessage:date="

+leString()+";message="

+y());

emsg=e();

=RECEIVE;

Bundlebd=newBundle();

ing("from",from);

ing("body",y());

a(bd);

ssage(msg);

}

}

}

下载模块

在主界面对着用户名长按,进入下载activity。进入activityFileTransfer,点击传输按钮

即可将文件传输给之前选择的用户,当然这里做得比较简单,并没有拒绝功能,一旦发现有

文件就接受。

FileTransferM

anagertransfer=newFileTransferManager(

tion);

Stringdestination=ur;

OutgoingFileT

ransferout=transfer

.createOutgoingFileTransfer(destination+

"/Smack");

那用户是如何监听到有文件并且接受呢?在进入主界面的时候就已经开始了一个rvice

(fileListenerService),该服务创建文件的监听类(XmppFileManager),监听类主要

继承FileTransferListener重写里面的fileTransferRequest方法。

FilesaveTo;

//tanswerToforrepliesandnd()

answerTo=

uestor();

if(!_(Environment

.getExternalStorageState())){

nd("ExternalMedianotmountedread/write");

return;

}el

if(!ctory()){

nd("The

directory"+olutePath()

+"isnotadirectory");

return;

}

saveTo=newFile(landingDir,eName());

if(()){

nd("Thefile

"+olutePath()+"alreadyexists");

//delete

();

//return;

}

IncomingFileT

ransfertransfer=();

nd("File

transfer:"+e()+"-"

+

eSize()/1024+"KB");

try{

veFile(saveTo);

nd("File

transfer:"+e()+"-"

+

tus());

doublepercent

s=0.0;

while(!transfe

()){

if(

Status().equals(_progress)){

percents=

((int)(gress()*10000))/100.0;

nd("File

transfer:"+e()+"-"

+percents+

"%");

}elif(tus().equals()){

nd(returnAndLogError(transfer));

return;

}

(1000);

}

if(tus().equals(te)){

nd("vedas"

+

olutePath());

}

el{

nd(returnAndLogError(transfer));

}

}catch(Exceptionex){

Stringmessage="Cannotreceivethefile

becauanerroroccuredduringtheprocess."

+ex;

Log.e(TAG,message,ex);

nd(message);

}

网上说文件的传输遇到几个比较重要的问题,我也查看了很多资料(国内的基本是寥寥无几,

对此我感到挺无奈的,只能看国外,这样每次我的英语水平都提高了太无奈了^0^)。在

这个androidasmack的最新版本好像是解决了几个比较重要的问题,剩下一个传输文件

没反应的问题我在初始化连接时调用了configure方法解决。不过不知道是不是这个原因,

后面出现了一个神奇的问题,就是有时可以成功传输有时传输时客户端没响应(如果有人完

美解决了这个问题,那就………赶紧将代码放出来一起共享^-^,以提高我国程序员的整体水

平,多伟大遥远的理想啊~~)。

项目下载

/not-code/

本文为原创翻译,如需转载,请注明作者和出处,谢谢!

出处:

/not-code/archive/2011/07/16/2108369.h

tml

本文发布于:2022-12-28 15:22:29,感谢您对本站的认可!

本文链接:http://www.wtabcd.cn/fanwen/fan/90/47351.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:报刊订阅网
下一篇:麓山就业网
标签:国外聊天室
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图