即时聊天的解决方案

  • socket:
  • xmpp:xmpp+openfire+asmack
  • 环信

常见协议

比较安全,tcp上还加了俩层

简单聊一下socket

socket:套接字,连接需要ip端口,分为tcp和udp两种形式

常见的术语

  • xmpp:基于xml的可拓展协议.
  • jabber:xmpp的前身.
  • openfire:支持xmpp的开源服务器
  • smack.jar:对xmpp协议封装.方便开发的jar包.
  • spark.exe:基于xmpp的pc客户端;
  • asmack.jar:smack.jar的精简版.专门针对android端开发

xmpp的认识.

  • xmpp官网:http://xmpp.org/
  • XMPP(可扩展消息处理现场协议)是基于可扩展标记语言(XML)的协议,它用于即时消息(IM)以及在线现场探测。 
    XMPP的前身是Jabber,一个开源形式组织产生的网络即时通信协议。 

xmpp特点:

  1. 开放: XMPP协议是自由、开放、公开的,并且易于了解。 而且在客户端 、 服务器 、 组件 、 源码库等方面,都已经各自有多种实现。
  2. 标准: 互联网工程工作小组( IETF )已经将Jabber的核心XML流协议以XMPP之名,正式列为认可的实时通信及Presence技术。 而XMPP的技术规格已被定义在RFC3920及RFC3921 。 任何IM供应商在遵循XMPP协议下,都可与Google Talk实现连接。
  3. 证实可用: 第一个Jabber(现在XMPP)技术是Jeremie Miller在1998年开发的,现在已经相当稳定;数以百计的开发者为XMPP技术而努力。 今日的互联网上有数以万计的XMPP服务器运作着,并有数以百万计的人们使用XMPP实时传讯软件。
  4. 分散式: XMPP网络的架构和电子邮件十分相像;XMPP核心协议通信方式是先创建一个stream,XMPP以TCP传递XML数据流,没有中央主服务器。 任何人都可以运行自己的XMPP服务器,使个人及组织能够掌控他们的实时传讯体验。
  5. 安全: 任何XMPP协议的服务器可以独立于公众XMPP网络(例如在企业内部网络中),而使用SASL及TLS等技术的可靠安全性,已自带于核心XMPP技术规格中。
  6. 可扩展: XML 命名空间的威力可使任何人在核心协议的基础上建造定制化的功能;为了维持通透性,常见的扩展由XMPP标准基金会 。 弹性佳 XMPP除了可用在实时通信的应用程序,还能用在网络管理、内容供稿、协同工具、文件共享、游戏、远程系统监控等。
  7. 多样性: 用XMPP协议来建造及布署实时应用程序及服务的公司及开放源代码计划分布在各种领域;用XMPP技术开发软件,资源及支持的来源是多样的,使得使你不会陷于被“绑架”的困境。

相关的下载

asmack github:https://github.com/Flowdalic/asmack
asmack下载地址1:http://asmack.freakempire.de/
asmack下载地址2:http://code.google.com/p/asmack/downloads/list
openfire下载地址:http://www.igniterealtime.org/downloads/index.jsp
smack使用指南:http://www.igniterealtime.org/builds/smack/docs/latest/documentation/index.html

openfire的安装

  1. 官网http://www.igniterealtime.org/
  2. 安装包的类型
    1. exe安装包-->点击exe根据提示安装
    2. zip包解压版-->解压放到指定目录就可以了.
  3. 首次运行的配置
    1. 配置语言-->中文简体
    2. 配置数据库形式-->内嵌数据库
    3. 配置服务器名称-->itheima
    4. 配置管理员账号密码-->admin admin。帐号就是这个,没有@xxx那些
  4. 创建用户
    1. admin admin
    2. hm1 111111

spark的安装-->xmpp客户端1

  • 直接下一步就可以完成
  • 运行
    • 1.配置服务器ip
    • 2.输入用户账号/密码

如意通的安装-->xmpp客户端2

pc端-服务器-pc端演示

smack常见api的查看.

xmpp版即使聊天的核心:其实就是熟悉asmack.jar里面的一些常见类.以及常见监听器;

工程搭建

  1. asmack.jar的下载,下载地址http://asmack.freakempire.de/
  2. 创建android工程.
  3. 添加jar包.添加依赖
  4. as关联源码.

引导页模块splashActivity

ThreadUtils的封装.

public class ThreadUtils {
    /**
     * 子线程执行task
     */
    public static void runInThread(Runnable task) {
        new Thread(task).start();
    }
    /**
     * 创建一个主线程中handler
     */
    public static Handler mHandler = new Handler();
    /**
     * UI线程执行task
     */
    public static void runInUIThread(Runnable task) {
        mHandler.post(task);
    }
}
public class  {
    /**
     * 可以在子线程中弹出toast
     *
     * @param context
     * @param text
     */
    public static void showToastSafe(final Context context, final String text) {
        ThreadUtils.runInUIThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
            }
        });
    }
}
 
 
 
SplashActivity
public class SplashActivity extends ActionBarActivity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_splash);
		// 停留3s,进入登录界面
		ThreadUtils.runInThread(new Runnable() {
			@Override
			public void run() {
				// 休眠3s
				SystemClock.sleep(3000);
				// 进入主界面
				Intent intent = new Intent(SplashActivity.this, LoginActivity.class);
				startActivity(intent);
				finish();
			}
		});
	}
}

  

登录模块LoginActivity

  1. 引入了ButterKnife.jar以及as的android-butterknife-zelezny插件
  2. ButterKnife:类似xutils中的viewUtils,可以注解的框架,图为关联源码,点右面
  3. 调用api登录

连接配置

// 设置常见的参数 config.setDebuggerEnabled(true);// 开启调试模式,可以看到传输的xml config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);//明文传输

public class LoginActivity extends ActionBarActivity {
    public static final String HOST = "192.168.1.100";    // 主机ip
    public static final int PORT = 5222;            // 对应的端口号
    public static final String SERVICENAME = "itheima.com";
    private TextView mEtUserName;
    private TextView mEtPassWord;
    private Button mBtnLogin;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        initView();
        initListener();
    }
    private void initListener() {
        mBtnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final String userName = mEtUserName.getText().toString();
                final String passWord = mEtPassWord.getText().toString();
                // 判断用户名是否为空
                if (TextUtils.isEmpty(userName)) {// 用户名为空,系统自带的textview的属性,弹出悬浮窗提示
                    mEtUserName.setError("用户名不能为空");
                    return;
                }
                // 判断密码是否为空
                if (TextUtils.isEmpty(passWord)) {// 用户名为空
                    mEtPassWord.setError("密码不能为空");
                    return;
                }
                ThreadUtils.runInThread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            // 1.创建连接配置对象
                            ConnectionConfiguration config = new ConnectionConfiguration(HOST, PORT);
                            // 额外的配置(方面我们开发,上线的时候,可以改回来)
                            config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);// 明文传输
                            config.setDebuggerEnabled(true);// 开启调试模式,方便我们查看具体发送的内容
                            // 2.开始创建连接对象
                            XMPPConnection conn = new XMPPConnection(config);
                            // 开始连接
                            conn.connect();
                            // 连接成功了
                            // 3.开始登录
                            conn.login(userName, passWord);
                            // 已经成功成功
                            ToastUtils.showToastSafe(LoginActivity.this, "登录成功");
                            finish();
                            // 跳到主界面
                            Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                            startActivity(intent);
                            // 需要保存连接对象
                            IMService.conn = conn;
                            //启动IMService
                            Intent service = new Intent(LoginActivity.this, IMService.class);
                            startService(service);
                        } catch (XMPPException e) {
                            e.printStackTrace();
                            ToastUtils.showToastSafe(LoginActivity.this, "登录失败");
                        }
                    }
                });
            }
        });
    }
    private void initView() {
        mEtUserName = (TextView) findViewById(R.id.et_username);
        mEtPassWord = (TextView) findViewById(R.id.et_password);
        mBtnLogin = (Button) findViewById(R.id.btn_login);
    }
}

  

主页面MainActivity

ToolBarUtil

public class ToolBarUtil {
    private List<TextView> mTextViews = new ArrayList<TextView>();
    public void createToolBar(LinearLayout container, String[] toolBarTitleArr, int[] iconArr) {
        for (int i = 0; i < toolBarTitleArr.length; i++) {
            TextView tv = (TextView) View.inflate(container.getContext(), R.layout.inflate_toolbar_btn, null);
            tv.setText(toolBarTitleArr[i]);
            // 动态修改textView里面的drawableTop属性
            tv.setCompoundDrawablesWithIntrinsicBounds(0, iconArr[i], 0, 0);
            int width = 0;
            int height = LinearLayout.LayoutParams.MATCH_PARENT;
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width, height);
            //设置weight属性
            params.weight = 1;
            container.addView(tv, params);
            //保存textView到集合中
            mTextViews.add(tv);
            //设置点击事件
            final int finalI = i;
            tv.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //不同模块之间传值需要用接口回调
                    //3.需要传值的地方.用接口对象调用接口方法
                    mOnToolBarClickListener.onToolBarClick(finalI);
                }
            });
        }
    }
    public void changeColor(int position) {
        //还原所有的颜色
        for (TextView tv : mTextViews) {
            tv.setSelected(false);
        }
        mTextViews.get(position).setSelected(true);//通过设置selected属性,控制为选中效果
    }
    //1.创建接口和接口方法
    public  interface  OnToolBarClickListener{
        void onToolBarClick(int position);
    }
    //2.定义接口变量
    OnToolBarClickListener mOnToolBarClickListener;
    //4.暴露一个公共的方法
    public void setOnToolBarClickListener(OnToolBarClickListener onToolBarClickListener) {
        mOnToolBarClickListener = onToolBarClickListener;
    }
}

  

 
MainActivity
public class MainActivity extends ActionBarActivity {
	@InjectView(R.id.main_tv_title)
	TextView				mMainTvTitle;
	@InjectView(R.id.main_viewpager)
	ViewPager				mMainViewpager;
	@InjectView(R.id.main_bottom)
	LinearLayout			mMainBottom;
	// xutils viewutils 注解方式去找控件
	// viewutils httpUitls dbutils bitmaputils
	//
	private List<Fragment>	mFragments	= new ArrayList<Fragment>();
	private ToolBarUtil		mToolBarUtil;
	private String[]		mToolBarTitleArr;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		ButterKnife.inject(this);
		initData();
		initListener();
	}
	private void initListener() {
		mMainViewpager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
			@Override
			public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
			}
			@Override
			public void onPageSelected(int position) {
				// 修改颜色
				mToolBarUtil.changeColor(position);
				// 修改title
				mMainTvTitle.setText(mToolBarTitleArr[position]);
			}
			@Override
			public void onPageScrollStateChanged(int state) {
			}
		});
		mToolBarUtil.setOnToolBarClickListener(new ToolBarUtil.OnToolBarClickListener() {
			@Override
			public void onToolBarClick(int position) {
				mMainViewpager.setCurrentItem(position);
			}
		});
	}
	private void initData() {
		// viewPager-->view-->pagerAdapter
		// viewPager-->fragment-->fragmentPagerAdapter-->fragment数量比较少
		// viewPager-->fragment-->fragmentStatePagerAdapter
		// 添加fragment到集合中
		mFragments.add(new SessionFragment());
		mFragments.add(new ContactsFragment());
		mMainViewpager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
		// 底部按钮
		mToolBarUtil = new ToolBarUtil();
		// 文字内容
		mToolBarTitleArr = new String[] { "会话", "联系人" };
		// 图标内容
		int[] iconArr = { R.drawable.selector_meassage, R.drawable.selector_selfinfo };
		mToolBarUtil.createToolBar(mMainBottom, mToolBarTitleArr, iconArr);
		// 设置默认选中会话
		mToolBarUtil.changeColor(0);
	}
	class MyPagerAdapter extends FragmentPagerAdapter {
		public MyPagerAdapter(FragmentManager fm) {
			super(fm);
		}
		@Override
		public Fragment getItem(int position) {
			return mFragments.get(position);
		}
		@Override
		public int getCount() {
			return 2;
		}
	}
}

  

7.xmpp版即时聊天的更多相关文章

  1. Asp.Net Mvc基于Fleck开发的多人网页版即时聊天室

    一.项目的核心说明 1.Fleck这个是实现websocket一个比较简单第三方组件,它不需要安装额外的容器.本身也就几个接口可供调用. 2.项目是基于.net framework 4.7.2 ,在v ...

  2. 即时聊天IM之三 XMPP协议客户端库的和Android端框架概述

    合肥程序员群:49313181.    合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入) Q  Q:408365330     E-Mail:egojit@qq.com smack ...

  3. 即时聊天 / XMPP

    MQTT是第二个即时聊天协议(了解) 5.即时通讯 即时通讯网上有第三方的解决方案,比如环信,融云等.我们是自己搭的xmpp服务器,服务器使用的tigase,之前写过相关的博客,自己去年也做了对应的w ...

  4. 几款web版整合(QQ、msn、icq、yahoo通、Gtalk等)即时聊天http://hi.baidu.com/ejie/blog/item/e89794ef9a9431efce1b3ebd.html

        直到近期为止,我们经常使用的即时聊天工具(QQ.msn等)了Web版,大家不用下载庞大软件,直接打开网页就能够与自己的好友聊天,很方便.在此将时汇总,便于大家查找,节约大家一点时间. 此都是官 ...

  5. iOS:XMPP即时聊天知识

    XMPP即时聊天框架:XMPPFramework   XMPP The Extensible Messaging and Presence Protocol(可扩展通讯和表示协议). 基于XML XM ...

  6. XMPP环境搭建 (mac环境下 安装自己独立的mysql与服务器(openfire),实现即时聊天功能)

    1简单概览 [一]XMPP简介 http://xmpp.org 即时通讯技术 IM - Instant Messaging ⽀支持⽤用户在线实时交谈.交谈双⽅方都需要⼀一个聊天窗⼝口,其中⼀一个⽤用户 ...

  7. Android基于xmpp的即时通讯应用

    xmpp是一个通信协议.因为这是个开放的协议,为了节俭开发成本,很多即时应用都采用了这个协议.Android上最常用的组合asmack +openfire.Asmack是smack的android版, ...

  8. 即时聊天IM之二 openfire 整合现有系统用户

    合肥程序员群:49313181.    合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入) Q  Q:408365330     E-Mail:egojit@qq.com  综述: ...

  9. 类似QQ的应用毗邻(Pilin)即时聊天源码

      这个应用是从安卓教程网分享过了的,个人觉得这个还是挺不错的,毗邻(Pilin)即时聊天应用源码,承诺的 基于xmpp openfire asmack 的即时聊天应用,继续完善,现在只完成了文字.表 ...

随机推荐

  1. jQuery.snowflake雪花飘落插件

    一.前言 前言:最近圣诞节来临,需要在页面上应用一个雪花飘落的效果,做之前产品经理给了我网络上的一个demo,地址是http://demo.lanrenzhijia.com/demo/1225/sd/ ...

  2. CocoStudio基础教程(4)骨骼动画的动态换肤

    1.概述 游戏中人物的状态会发生改变,而这种改变通常要通过局部的变化来表现出来.比如获得一件装备后人物形象的改变,或者战斗中武器.防具的损坏等.这些变化的实现就要通过动态换肤来实现. 2.运行到程序 ...

  3. Swift Tour 随笔总结 (3)

    关于Optional的Control Flow if let constantName = someOptional { statements } 如果该Optional为nil,则不进入if,否则执 ...

  4. Sort List

    采用归并排序,通过定义快.慢两个指针来找到中点,再采用之前的排序算法进行归并. ListNode *listSort(ListNode *head) { //定义快慢指针,找到链表中心 ListNod ...

  5. [转载]WiFi有死角? 巧用旧无线路由器扩展覆盖

    怎么了,家里的WiFi有死角?老旧无线路由器的无线覆盖不给力?现在大功率无线产品或双频无线产品的售价并不便宜,而且仅靠一台无线路由器并不能满足多户型家庭的无线覆盖需求.那么,是不是有什么廉价而又实用的 ...

  6. 菜鸟带你飞______DP基础26道水题

    DP 158:11:22 1205:00:00   Overview Problem Status Rank (56) Discuss Current Time: 2015-11-26 19:11:2 ...

  7. HXOI 2014 PSet 4 Day 1 一模04日1 题解

    1. 最小花费(money.pas/c/cpp) 问题描述 在n个人中,某些人的银行账号之间可以互相转账.这些人之间转账的手续费各不相同.给定这些人之间转账时需要从转账金额里扣除百分之几的手续费,请问 ...

  8. 快速传输大数据(tar+lz4+pv)

    快速传输大数据(tar+lz4+pv)   如果用传统SCP远程拷贝,速度是比较慢的.现在采用lz4压缩传输.LZ4是一个非常快的无损压缩算法,压缩速度在单核300MB/S,可扩展支持多核CPU.它还 ...

  9. VMware安装64位操作系统提示Intel VT-x处于禁用状态的解决办法

    用VMware安装64位操作系统时,如果目前本地的操作系统是64位的,那么可以说明CPU是肯定支持64位的,这时候如果提示此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态.这个 ...

  10. Java面向对象的多态

    Java中多态的概念是面向对象中除封装和继承外非常重要的知识点,也是Java面向对象三大特性最后一个特性 多态其实就是指对象存在的多种形态,多态分为引用多态和方法多态 引用多态的含义就是:父类的引用可 ...