xmpp instant chat

Posted by pacman on Wed, 12 Jan 2022 10:27:09 +0100

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. 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

  1. Official website http://www.igniterealtime.org/
  2. Type of installation package
    1. Exe installation package -- > Click exe to install according to the prompt
    2. The unzipped version of the zip package -- > can be unzipped into the specified directory
  3. First run configuration
    1. Configuration language -- > Chinese Simplified
    2. Configuration database form -- > embedded database
    3. Configuration server name -- > itheima
    4. Configure administrator account password -- > admin admin. This is the account number, not @ xxx
  4. Create user
    1. admin admin
    2. 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

  1. asmack.jar download, download address http://asmack.freakempire.de/
  2. Create an android project
  3. Add jar package Add dependency
  4. 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

  1. Butterknife Android button knife zelezny plug-in for jar and as
  2. ButterKnife: similar to viewUtils in xutils, it can annotate the framework. The figure shows the associated source code. Click on the right
  3. 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;
		}
	}
}