Instant chat solution
- socket:
- xmpp:xmpp+openfire+asmack
- Huanxin
Common protocols

It is relatively safe. Two layers are added to tcp

Let's talk about socket
Socket: socket. ip and port are required for connection. It is divided into two forms: tcp and udp
Common terms
- xmpp: Extensible protocol based on xml
- Jabber: the predecessor of XMPP
- openfire: open source server supporting xmpp
- smack.jar: encapsulate xmpp protocol Easy to develop jar package
- spark.exe: pc client based on xmpp;
- asmack.jar:smack.jar Specifically developed for android

Understanding of xmpp
- xmpp official website: http://xmpp.org/
- XMPP (extensible message processing field protocol) is a protocol based on extensible markup language (XML), which is used for instant messaging (IM) and online field detection. The predecessor of XMPP is Jabber, a network instant messaging protocol produced by an open source organization.
xmpp features:
- Open: XMPP protocol is free, open, open and easy to understand. And in the client, server, components, source code library and so on, they have been implemented in a variety of ways.
- Standard: the Internet Engineering Working Group (IETF) has officially listed Jabber's core XML streaming protocol as a recognized real-time communication and Presence technology in the name of XMPP. The technical specifications of XMPP have been defined in RFC3920 and RFC3921. Any IM provider can connect with Google Talk under the XMPP protocol.
- Confirmed availability: the first jabber (now XMPP) technology was developed by Jeremie Miller in 1998 and is now quite stable; Hundreds of developers are working for XMPP technology. Today, there are tens of thousands of XMPP servers running on the Internet, and millions of people use XMPP real-time messaging software.
- Decentralized: the architecture of XMPP network is very similar to that of e-mail; The communication mode of XMPP core protocol is to create a stream first. XMPP transmits XML data stream through TCP without a central master server. Anyone can run their own XMPP server, enabling individuals and organizations to control their real-time messaging experience.
- Security: the server of any XMPP protocol can be independent of the public XMPP network (for example, in the enterprise internal network), and the reliable security using SASL, TLS and other technologies has been included in the core XMPP technical specifications.
- Extensibility: the power of XML namespace enables anyone to build customized functions based on the core protocol; To maintain permeability, common extensions are provided by the XMPP standards foundation. Good flexibility XMPP can be used not only in real-time communication applications, but also in network management, content contribution, collaboration tools, file sharing, games, remote system monitoring, etc.
- Diversity: companies and open source programs that use XMPP protocol to build and deploy real-time applications and services are distributed in various fields; There are various sources of resources and support for developing software with XMPP technology, so that you won't be "kidnapped".
Related downloads
asmack github: https://github.com/Flowdalic/asmack asmack Download address 1: http://asmack.freakempire.de/ asmack Download address 2: http://code.google.com/p/asmack/downloads/list openfire Download address: http://www.igniterealtime.org/downloads/index.jsp smack Use guide: http://www.igniterealtime.org/builds/smack/docs/latest/documentation/index.html
Installation of openfire
- Official website http://www.igniterealtime.org/
- Type of installation package
- Exe installation package -- > Click exe to install according to the prompt
- The unzipped version of the zip package -- > can be unzipped into the specified directory
- First run configuration
- Configuration language -- > Chinese Simplified
- Configuration database form -- > embedded database
- Configuration server name -- > itheima
- Configure administrator account password -- > admin admin. This is the account number, not @ xxx
- Create user
- admin admin
- hm1 111111
spark installation -- > XMPP client 1
- It can be done directly in the next step
- function
- 1. Configure server ip
- 2. Enter user account / password
Installation of ruyitong -- > XMPP client 2
pc server pc demo
smack common api view
xmpp version even the core of chat: in fact, it is familiar with asmack Some common classes in jar And common listeners;
Engineering construction
- asmack.jar download, download address http://asmack.freakempire.de/
- Create an android project
- Add jar package Add dependency
- as associated source code
Bootpage module splashActivity
Encapsulation of ThreadUtils
public class ThreadUtils { /** * The child thread executes the task */ public static void runInThread(Runnable task) { new Thread(task).start(); } /** * Create a handler in the main thread */ public static Handler mHandler = new Handler(); /** * UI Thread execution task */ public static void runInUIThread(Runnable task) { mHandler.post(task); } } public class { /** * You can pop up toast in a child thread * * @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); // Stay for 3s and enter the login interface ThreadUtils.runInThread(new Runnable() { @Override public void run() { // Sleep for 3s SystemClock.sleep(3000); // Enter the main interface Intent intent = new Intent(SplashActivity.this, LoginActivity.class); startActivity(intent); finish(); } }); } }
Login module LoginActivity
- Butterknife Android button knife zelezny plug-in for jar and as
- ButterKnife: similar to viewUtils in xutils, it can annotate the framework. The figure shows the associated source code. Click on the right
- Call api login
Connection configuration
//Set the common parameter config setDebuggerEnabled(true);// Open the debugging mode, and you can see the transferred XML config setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);// Plaintext transmission
public class LoginActivity extends ActionBarActivity { public static final String HOST = "192.168.1.100"; // Host ip public static final int PORT = 5222; // Corresponding port number 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(); // Judge whether the user name is empty if (TextUtils.isEmpty(userName)) {// If the user name is empty, the system's own textview attribute will pop up a floating window prompt mEtUserName.setError("User name cannot be empty"); return; } // Determine whether the password is empty if (TextUtils.isEmpty(passWord)) {// User name is empty mEtPassWord.setError("Password cannot be empty"); return; } ThreadUtils.runInThread(new Runnable() { @Override public void run() { try { // 1. Create connection configuration object ConnectionConfiguration config = new ConnectionConfiguration(HOST, PORT); // Additional configuration (we develop it and can change it back when we go online) config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);// Plaintext transmission config.setDebuggerEnabled(true);// Turn on the debugging mode to facilitate us to view the specific content sent // 2. Start creating connection object XMPPConnection conn = new XMPPConnection(config); // Start connection conn.connect(); // The connection succeeded // 3. Start login conn.login(userName, passWord); // Has succeeded ToastUtils.showToastSafe(LoginActivity.this, "Login succeeded"); finish(); // Skip to the main interface Intent intent = new Intent(LoginActivity.this, MainActivity.class); startActivity(intent); // The connection object needs to be saved IMService.conn = conn; //Start IMService Intent service = new Intent(LoginActivity.this, IMService.class); startService(service); } catch (XMPPException e) { e.printStackTrace(); ToastUtils.showToastSafe(LoginActivity.this, "Login failed"); } } }); } }); } private void initView() { mEtUserName = (TextView) findViewById(R.id.et_username); mEtPassWord = (TextView) findViewById(R.id.et_password); mBtnLogin = (Button) findViewById(R.id.btn_login); } }
Main page 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]); // Dynamically modify the drawableTop property in textView tv.setCompoundDrawablesWithIntrinsicBounds(0, iconArr[i], 0, 0); int width = 0; int height = LinearLayout.LayoutParams.MATCH_PARENT; LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width, height); //Set the weight property params.weight = 1; container.addView(tv, params); //Save textView to collection mTextViews.add(tv); //Set click event final int finalI = i; tv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Interface callback is required for value transfer between different modules //3. Where value transfer is required Calling interface methods with interface objects mOnToolBarClickListener.onToolBarClick(finalI); } }); } } public void changeColor(int position) { //Restore all colors for (TextView tv : mTextViews) { tv.setSelected(false); } mTextViews.get(position).setSelected(true);//Set the selected property to control the selected effect } //1. Create interfaces and interface methods public interface OnToolBarClickListener{ void onToolBarClick(int position); } //2. Define interface variables OnToolBarClickListener mOnToolBarClickListener; //4. Expose a public method 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 annotation control // 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) { // Modify color mToolBarUtil.changeColor(position); // Modify 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 -- > the number of fragments is relatively small // viewPager-->fragment-->fragmentStatePagerAdapter // Add fragment to collection mFragments.add(new SessionFragment()); mFragments.add(new ContactsFragment()); mMainViewpager.setAdapter(new MyPagerAdapter(getSupportFragmentManager())); // Bottom button mToolBarUtil = new ToolBarUtil(); // Text content mToolBarTitleArr = new String[] { "conversation", "contacts" }; // Icon content int[] iconArr = { R.drawable.selector_meassage, R.drawable.selector_selfinfo }; mToolBarUtil.createToolBar(mMainBottom, mToolBarTitleArr, iconArr); // Set default selected session 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; } } }