基于mina开发的windows客户端和android客户端
server端和windows客户端就是mina官方的源码.
android客户端已经在android2.3.7以及android4.0.3上测试server端 入口地址为 org.apache.mina.example.chat Main.classwindows客户端 入口地址为 org.apache.mina.example.chat.client SwingChatClient.class================================================================================
android 部分源码
package com.example.minaim;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import org.apache.mina.core.filterchain.IoFilter;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.SocketConnector;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.StrictMode;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.example.minaim.ClientHandler.Callback;
public class MainActivity extends Activity implements Callback {
private ClientHandler ch;
private TextView msgContent;
@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle savedInstanceState) {
// /---------------------
init();
// /---------------------
super.onCreate(savedInstanceState);
System.setProperty("java.net.preferIPv6Addresses", "false");
setContentView(R.layout.activity_main);
msgContent = (TextView) findViewById(R.id.msgTxt);
Button sendBtn = (Button) findViewById(R.id.sendBtn);
final EditText sendContent = (EditText) findViewById(R.id.sendContent);
msgContent.setEllipsize(TextUtils.TruncateAt.MARQUEE);
msgContent.setMarqueeRepeatLimit(6);
SocketConnector connector = new NioSocketConnector();
IoFilter filter = new ProtocolCodecFilter(new TextLineCodecFactory());
connector.getFilterChain().addLast("vestigge", filter);
SocketAddress soketAddress = new InetSocketAddress("192.168.11.103",
1234);
ch = new ClientHandler(MainActivity.this);
connector.setHandler(ch);
ConnectFuture future = connector.connect(soketAddress);
future.join();
if (!future.isConnected()) {
System.out.println("连接服务器失败");
future.getException().printStackTrace();
return;
} else {
final IoSession session = future.getSession();
sendContent.setText("");
session.write("LOGIN " + System.currentTimeMillis() + "\r\n");
session.write("BROADCAST Helloworld\r\n");
sendBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String sendMsgText = "BROADCAST "
+ sendContent.getText().toString() + "\r\n";
System.out.println(sendMsgText);
session.write(sendMsgText);
sendContent.setText("");
}
});
}
}
@Override
public void connected() {
// TODO Auto-generated method stub
}
@Override
public void loggedIn() {
// TODO Auto-generated method stub
}
@Override
public void loggedOut() {
// TODO Auto-generated method stub
}
@Override
public void disconnected() {
// TODO Auto-generated method stub
}
@Override
public void messageReceived(String message) {
// BROADCAST OK user6: vg
String[] result = message.split(" ", 3);
String status = result[1];
System.out.println(status);
if ("OK".equals(status)) {
msg = new StringBuilder(result[2]);
mHandler.postDelayed(mUpdateUITimerTask, 0);
}
}
private StringBuilder msg;
// 用于刷新textview, 对于UI的更改要放在线程中
private final Runnable mUpdateUITimerTask = new Runnable() {
public void run() {
msgContent.append(msg + "\r\n");
final int maxY = (msgContent.getLineCount()
* msgContent.getLineHeight() + msgContent.getPaddingTop() + msgContent
.getPaddingBottom()) - msgContent.getHeight();
msgContent.scrollTo(0, maxY);
msgContent.invalidate();
Log.v("height", maxY + "");
}
};
private final Handler mHandler = new Handler();
@Override
public void error(String message) {
// TODO Auto-generated method stub
}
private long exitTime = 0;
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK
&& event.getAction() == KeyEvent.ACTION_DOWN) {
if ((System.currentTimeMillis() - exitTime) > 2000) {
Toast.makeText(getApplicationContext(), "再按一次退出程序",
Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
} else {
finish();
System.exit(0);
}
return true;
}
return super.onKeyDown(keyCode, event);
}
// 判断版本格式,如果版本 > 2.3,就是用相应的程序进行处理,以便影响访问网络
@TargetApi(9)
private static void init() {
String strVer = android.os.Build.VERSION.RELEASE; // 获得当前系统版本
strVer = strVer.substring(0, 3).trim(); // 截取前3个字符 2.3.3转换成2.3
float fv = Float.valueOf(strVer);
if (fv > 2.3) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads().detectDiskWrites().detectNetwork()
.penaltyLog().build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects().penaltyLog().penaltyDeath()
.build());
}
}
}
================================================================================
效果图如下:
(貌似图片过大,只显示了2/3,请在新页面中单独打开图片)