使用superSocket做服务端,android作客户端,android实现登录功能
superSocket的配置请看官网
服务端,新建登录命令
如下
public class LOGIN : StringCommandBase<MyAppSession>{
public LOGIN()
{
Console.WriteLine("加载命令LOGIN");
}
public override void ExecuteCommand(MyAppSession session, StringRequestInfo requestInfo)
{
Console.WriteLine("收到命令消息LOGIN");
if (requestInfo.Parameters == null || requestInfo.Parameters.Length != 2)
return;
var username = requestInfo.Parameters[0];
var password = requestInfo.Parameters[1];
if("1".Equals(username) && "2".Equals(password))//这里可以从数据库获取,比较
{
//获取所有连接的用户
var sessionClient = session.AppServer.GetAllSessions().Where(c => c.userID == username).SingleOrDefault();
if (sessionClient != null)
{//说明已经有重复的用户登录,向旧的连接发送消息
sessionClient.Send("有新的用户登入,你将被强制下线");
sessionClient.Close();//关闭就连接
}
session.IsLoggedIn = true;
Console.WriteLine("用户名>" + username + " 密码>" + password+" 登入成功");
}
}
}
AppSession我定义如下
public class MyAppSession : AppSession<MyAppSession>
{
/// <summary>
/// 用户的唯一id
/// </summary>
public string userID { get; set; }
public bool IsLoggedIn { internal set; get; }
protected override void OnSessionStarted()
{
this.Send("成功连接服务端 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
Console.WriteLine("有新的用户连接上来啦" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\n SessionID=" +
this.SessionID + "\nAddress=" + this.RemoteEndPoint.Address.ToString());
}
protected override void HandleUnknownRequest(StringRequestInfo requestInfo)
{
this.Send("Unknow request");
}
protected override void HandleException(Exception e)
{
this.Send("Application error: {0}", e.Message);
}
protected override void OnSessionClosed(CloseReason reason)
{
base.OnSessionClosed(reason);
}
}
}
---------------------------------------android 客户端-----------------------------------------------------
/**
* @author 链接服务器回调
*
*/
public interface ICoallBack
{
/**
* 连接成功事件
* **/
public void OnSuccess(Socket client);
/**
* 连接失败事件
* **/
public void OnFailure(Exception e);
}
/**
* @author 发送接口回调
*
*/
public interface ISendResult
{
void OnSendSuccess();
void OnSendFailure(Exception e);
}
/**
* @author 接收消息回调
*
*/
public interface ISocketPacket
{
void SocketPacket(String msg);
}
//放常数的类
public class IPList
{
/*** 服务端ip ***/
public static final String _ip = "192.168.2.100";
/*** 服务端的通讯端口 ***/
public static final int _Port = 2016;
}
/**
* @author 接收消息线程
*
*/
public class MsgReceiveThread extends Thread implements Runnable
{
Socket _Client;
Handler handler;
BufferedReader in;
public MsgReceiveThread(Socket _Client, Handler handler)
{
this._Client = _Client;
this.handler = handler;
}
@Override
public void run()
{
super.run();
try
{
String line = "";
if (_Client != null)
{
in = new BufferedReader(new InputStreamReader(_Client.getInputStream()));
while ((line = in.readLine()) != null)
{
System.out.print("收到服务端消息" + line);
Message message = new Message();
message.what = SocketClient.RECEIVEMESSAGE;
message.obj = line;
handler.sendMessage(message);
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
/**
* @author 发送消息线程
*
*/
public class SendMsgThread extends Thread implements Runnable
{
Handler handler;
OutputStream serverOutput;
Object msg = null;
public SendMsgThread(Socket Client, Handler handler, Object msg)
{
try
{
serverOutput = Client.getOutputStream();
this.msg = msg;
}
catch (IOException e)
{
e.printStackTrace();
}
this.handler = handler;
}
@Override
public void run()
{
super.run();
Message message = new Message();
try
{
byte[] data = toByteArray(msg);
serverOutput.write(data);
serverOutput.flush();
message.what = SocketClient.SENDSUCCESS;
}
catch (Exception ste)
{
message.what = SocketClient.SENDFAILURE;
message.obj = ste;
}
handler.sendMessage(message);
}
/**
* @param obj转换byte
* @return
*/
public byte[] toByteArray(Object obj)
{
try
{
return obj.toString().getBytes("utf-8");
}
catch (UnsupportedEncodingException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
/**
* android Socket客户端封装
*
*/
@SuppressLint("HandlerLeak")
public class SocketClient
{
private Socket Client;
private OutputStream serverOutput = null;
private String host;
private int port = -1;
private int timeout = 3;
private ICoallBack CoallBack = null;
private ISocketPacket _packet = null;
private ISendResult _Result = null;
/**
* @param host
* ip地址
* @param port端口号
* @param timeOut
* 链接超市时间 秒
*/
public SocketClient(String host, int port, int timeOut)
{
this.host = host;
this.port = port;
this.timeout = timeOut;
}
/**
* @param 设置连接服务器监听
*/
public void setOnConnectListener(ICoallBack CoallBack)
{
this.CoallBack = CoallBack;
}
/** 连接成功 **/
public static final int CONNECTSUCCESS = 1;
/** 连接失败 **/
public static final int CONNECTFAILURE = -1;
/** 接收消息 **/
public static final int RECEIVEMESSAGE = 2;
/** 发送消息 **/
public static final int SENDMESSAGE = 3;
/** 发送成功 **/
public static final int SENDSUCCESS = 4;
/** 发送失败 **/
public static final int SENDFAILURE = -2;
public Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);
if (msg.what == CONNECTSUCCESS)
{
new MsgReceiveThread(Client, handler).start();
}
else if (msg.what == CONNECTFAILURE)
{
Exception e1 = (Exception) msg.obj;
if (CoallBack != null)
{
CoallBack.OnFailure(e1);
}
}
else if (msg.what == RECEIVEMESSAGE)
{
if (_packet != null)
{
_packet.SocketPacket(msg.obj.toString());
}
}
else if (msg.what == SENDMESSAGE)
{
new SendMsgThread(Client, handler, msg.obj).start();
}
else if (msg.what == SENDSUCCESS)
{
if (_Result != null)
{
_Result.OnSendSuccess();
}
}
else if (msg.what == SENDFAILURE)
{
if (_Result != null)
{
Exception e = (Exception) msg.obj;
_Result.OnSendFailure(e);
}
}
}
};
/**
* @param _packet设置接受消息监听
*/
public void setOnReceiveListener(ISocketPacket _packet)
{
this._packet = _packet;
}
/**
* 打开连接
*
* @return boolean
*/
public void Connection()
{
Thread thread = new Thread(new Runnable()
{
@Override
public void run()
{
Message message = new Message();
try
{
Client = new Socket(host, port);
Client.setSoTimeout(timeout * 3000);
if (CoallBack != null)
{
CoallBack.OnSuccess(Client);
}
Log.d("Client", "Socket链接成功");
message.what = CONNECTSUCCESS;
handler.sendMessage(message);
}
catch (Exception e1)
{
message.what = CONNECTFAILURE;
message.obj = e1;
e1.printStackTrace();
Log.d("Client", "连接失败");
}
}
});
thread.start();
}
/**
* 关闭连接的输入输出流
*
* @author mick.ge
*/
public void closeConnection()
{
try
{
if (Client != null)
{
Client.close();// 关闭socket
}
}
catch (Exception e)
{
}
}
public void SenddData(Object msg, ISendResult _Result)
{
this._Result = _Result;
Message message = new Message();
message.obj = msg;
message.what = SENDMESSAGE;
handler.sendMessage(message);
}
/**
* 发送数据
*
* @param sndStr
* @return boolean
*/
public boolean SenddData(String sndStr)
{
try
{
serverOutput.write(sndStr.getBytes());
serverOutput.flush();
return true;
}
catch (SocketTimeoutException ste)
{
closeConnection();
return false;
}
catch (Exception e)
{
closeConnection();
return false;
}
}
}
最后SocketClient的使用如下
SocketClient client = new SocketClient(IPList._ip, IPList._Port, 6);
client.Connection();//连接服务器
//设置接收消息监听
client.setOnReceiveListener(new ISocketPacket()
{
@Override
public void SocketPacket(String msg)
{
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
}
});
//设置连接服务器监听
client.setOnConnectListener(new ICoallBack()
{
@Override
public void OnSuccess(Socket client1)
{
}
@Override
public void OnFailure(Exception e)
{
}
});
//重要的在这
发送登入命令
因为supersocket内置的命令必须是\r\n结尾,已空格来分割,
LOGIN对应的是服务端的登入命令1 和2之间必须要有空格,相当于name和pwd,
client.SenddData("LOGIN 1 2\r\n", new ISendResult()
{
@Override
public void OnSendSuccess()
{
}
@Override
public void OnSendFailure(Exception e)
{
}
});
最后测试,上传效果图
哇咔咔,大功告成。