Instant Messaging is now very widely used in mobile applications, with TCP long links to achieve real-time data updates, notifications, often used in daily development. Today I will be in common development in the basic realization of the idea of the exchange with you. Reprint please indicate the source: http://blog.csdn.net/mr_oorange/article/details/52353626
Source Address: Https://github.com/Ooorange/java-TCP-long-connection
One: the preparation stage
The Android client is used to receive and send messages, and a Java local server implements the forwarding of messages.
Second: The realization of ideas
How to do instant messaging of messages, 1 is via HTTP rotation 2 is a long link service via HTTP (a bit like TCP, but there is still the possibility of disconnection, very large), 3 is a long connection based on TCP. Compare the pros and cons of the implementation scenario in the next 3: the first, the disadvantage: consumption of traffic, loss performance, TCP will continue to open the stop, the advantages: simple to implement; second, disadvantage: the need for service-side coordination, and HTTP disconnect is very high, not easy to control, the advantages: to achieve an acceptable instant communication Third: The connection through the heartbeat is not often disconnected, can achieve instant communication, and can customize the head, reduce the consumption of traffic. Shortcomings need backstage coordination, to achieve more complex (understanding are all right in fact). I chose the third option. A Java-based TCP long link.
Client and service-side contract conditions:
The server ends by setting timeout to terminate the receipt of the message and sending the client message. Specific values can be set themselves, in fact, is the perception of the client heartbeat. The socket on the service side remains open to accept connections from multiple clients, each newly added client identifies a unique ID, is used for directed delivery, the storage of off-line messages, sending, the encapsulation of the custom protocol, and the unpack;
Android Client implementation: maintains the sending and termination of message tasks through a thread pool. Tasks include: access to the input and output stream through the socket, set timeout time, when the arrival of the input and output is not available, up to 3 threads to keep the message received, sent and distributed, there is also a heart jumper to maintain the connection with the server (otherwise the server will think you timeout GG, will give you disconnect); Another important place is to implement a custom protocol that breaks down different lines of business, can be used for push, instant chat, etc. ... Client or Reality offline message store (ORM mode Greendao)
Service-side implementations: The same serversocket gets the input and output stream, and remains connected to the open state, the unique ID for each newly added client, used to redirect the message, and when the client is active or timeout to close the flow pipe,
Three: On the code
Client:
import com.orange.blog.net.protocol.ChatMsgProcotol;
Import Java.util.concurrent.ExecutorService;
Import java.util.concurrent.Executors; /** * Long Link: Problem description * Q1: The server and client sockets in the input and output stream will not be closed, so you need to consider resources to release the long link time * * Q2 when the link is closed, client and server side, can not close any socket input stream or output stream, otherwise socket communication
will be closed;
* Because all do not close the connection, and the Read method is blocked, will read the data, do not know when to read the end (when you know the end of this data read); * * * * * * Q3 If there are multiple business needs to use links, how to compatible with other business, so that the resolution process consistent * * * Q1 Solution: The server side is set to timeout, that is, timeout, if more than timeout server received no data, * then the server
Closes the connection so that server resources are used efficiently. * Q2 Solution: Agreed communication protocol, such as specific characters, or the use of Baotou + package, the way to pass data, Baotou fixed length, * inside the storage length of the package, such as information, so that the server will know when the end of the reading. The following is the code: * * Q3 Solution: Different business definitions of different protocols, such as Heartbeat Protocol, business protocol; Another scenario is a practical JSON data format for transmission * @Link (http://blog.csdn.net/ljl157011/article/details/19291611) * Short link: After the establishment of a communication will be released,
The next time you send a relink build, waste resources * Created by orange on 16/6/8. */public class Tcplongconnectclient {
The message is added by caching the thread pool and the
executorservice executorservice= executors.newcachedthreadpool () is disconnected;
Requesttask Requesttask;
Public tcplongconnectclient (Tcprequestcallback tcprequestcallback) {
requesttask=new requesttask ( Tcprequestcallback);
Executorservice.execute (Requesttask);
}
public void Addnewrequest (Chatmsgprocotol data) {
if (requesttask!=null)
requesttask.addrequest (data);
} Public
void Closeconnect () {
requesttask.stop ();
}
}
Client Core Task code:
/** * Implements a timed 5-second send a heartbeat * Created by Orange on 16/6/8.
* * Public class Heartbeattask implements Runnable {private static final int repeattime = 4000;
Private volatile Boolean iskeepalive = true;
Private OutputStream OutputStream;
Private String uuid;
Public Heartbeattask (OutputStream outputstream,string uuid) {this.outputstream = OutputStream;
This.uuid=uuid; @Override public void Run () {try {iskeepalive) {Socketutil.write
Content2stream (New Heartbeatprotocol (), outputstream);
try {thread.sleep (repeattime);
catch (Interruptedexception e) {e.printstacktrace ();
} if (OutputStream!= null) {Socketutil.closestream (outputstream);
The catch (Exception e) {log.d ("Exception", ":", "request" + "has been closed."); E.printstacktrace ();
finally {if (OutputStream!= null) {Socketutil.closestream (outputstream);
}} public void Setkeepalive (Boolean iskeepalive) {this.iskeepalive = iskeepalive; }
}
send and receive messages
@Override public void Run () {uuid = Projectapplication.getuuid ();
try {failedmessage (0, "Server in Connection");
try {socket = Socketfactory.getdefault (). Createsocket (address, PORT);
}catch (connectexception e) {failedmessage (-1, "Service Area Connection exception, please check network");
Return
} senddata.add (New Registerprocotol ());
Senddata.add (New Userfriendreuqestprocotol ());
Sendtask=new Sendtask ();
Sendtask.outputstreamsend = Socket.getoutputstream ();
Sendtask.start ();
Recivertask = new Recivertask ();
Recivertask.inputstreamreciver = Socket.getinputstream ();
Recivertask.start ();
if (islongconnection) {heartbeattask = new Heartbeattask (sendtask.outputstreamsend, UUID);
Executorservice = Executors.newcachedthreadpool (); Executorservice.execute (Heartbeattask);
The catch (IOException e) {failedmessage ( -1, "IOException");
E.printstacktrace (); }
}
The customization of communication protocol and the solution package
Public abstract class Basicprotocol {The version of public static final int version_len=2;//protocol public static final int comme Type of nd_len=4;//protocol: 0000 Heartbeat, 0001 normal text chat, 0002 Server return protocol, 0003 buddy list request, 0004 User Registration Connection Agreement public static String version= "00";
The current version number of dead public static String Parasecommend (byte[] data) {return new string (Data,version_len,commend_len);
Public abstract String getcommend ();
Public byte[] Getcontentdata () {bytearrayoutputstream baos=new bytearrayoutputstream (Version_len+commend_len);
Baos.write (Version.getbytes (), 0,version_len);
Baos.write (Getcommend (). GetBytes (), 0,commend_len);
return Baos.tobytearray (); public int parsebinary (byte[] data) throws Protocolexception {string Version=new string (Data,0,version_len
);
Version=version;
if (!version.equals) {throw new Protocolexception ("Income version is error" +version);
return Version_len+commend_len;
}}
The code is a bit messy, the service-side code is not posted, if you need to please point here is the source , https://github.com/Ooorange/java-TCP-long-connection Welcome Fork,star
Reprint Please indicate the source
Baidu Search: I have resources, or direct access to this link: https://www.woyouziyuan.com, personally do the magnetic seed sharing links