Chat rooms based on push technology are now common in China. The biggest feature of this chat room is that the server does not regularly write chat content to the client without refreshing the browser for a period of time. When someone speaks, new chat content appears on the screen, and the chat content keeps rolling up. If the browser status bar is located, you can see that the progress bar is always on the download page. Even if the chat room contains hundreds of people, the performance will not be significantly reduced. In the past, the performance of chat rooms made by CGI or active server scripts was obviously insufficient.
The basic principle of chatting rooms for pushing technology is that, without using the httpd server program, the socket program listens to port 80 of the server. According to the HTML specification, after receiving browser requests, simulates the response of the WWW server and sends the chat content back to the browser. In the browser's view, it is always in the page receiving status like browsing a huge page. That is to say, we no longer use CGI or other methods to process chat content, but use our own programs to process all transactions. In fact, it is a dedicated Chat Server, that is, a simplified WWW server dedicated for chatting.
Before discussing the implementation of the program, let's first analyze the related technologies.
◆ HTTP request and Response Process
HTTP is the standard for communication between browsers and WWW servers. Socket chat servers must comply with this Protocol. In fact, we only need to use a small part of it.
HTTP uses the C/S (Client/Server) mode, where the browser is an HTTP client. browsing a page is actually opening a socket connection and sending a request to the WWW server, the server sends a response to the browser based on the requested resource and closes the connection. The request and response between the customer and the server have certain format requirements. As long as the request is received and sent in this format, the browser will normally display the content you need.
The request and response have a similar structure, including:
· An initial line
· Zero or multiple headers lines
· A blank line
· Optional information
Let's look at the request sent by a browser:
When we browse the Web page:
GET/path/file.html HTTP/1.0
From: someuser@somehost.com
User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.0; digext)
[Empty rows]
The first line of get/path/file.html HTTP/1.0 is the core of our processing. It consists of three parts separated by spaces: Method: Get, request Resource:/path/file.html, HTTP Version: HTTP/1.0.
The server will respond with the following information through the same socket:
HTTP/1.0 200 OK
Date: Fri, 31 Dec 1999 23:59:59 GMT
Content-Type: text/html
Content-Length: 1354
<HTML>
<Body>
<H1> Hello world! </H1>
(Other content )...
</Body>
</Html>
The first line also contains three parts: HTTP Version, status code, and description related to the status code. Status Code 200 indicates that the request is successful.
After an answer is sent, the server closes the socket.
◆ Server Model
Generally, network servers are divided into two types:
(1) Cyclic server (iterative server): It is a server that can only process one request at a time. The simultaneous arrival of multiple requests will be placed in the Request queue. The TCP socket server rarely uses the loop mode, because if a connection problem occurs between a customer and the server, the entire server will be suspended. It is usually used by UDP socket servers.
(2) Concurrent Server: after each request arrives, a new process is generated to process the connection generated by the request. Most TCP socket servers provide services in concurrency mode.
Concurrent servers can be implemented in multiple ways:
The I server connects to each received client and creates a new sub-process to process the client request.
The II server creates multiple sub-processes in advance to process client requests. This method is called a "prefork" server.
III The server uses the select function to achieve multiplexing of multiple client connections.
IV super server (Inet) activated server.
Concurrent servers have inherent fast response advantages due to their algorithms, and when a user communicates with the server, the deadlock does not affect other processes, however, as multiple processes need to exchange information through inter-process communication, and the overhead of the new fork process increases as the number of users increases, therefore, the original concurrent server is not necessarily the best choice. Java brings us a convenient thread mechanism, so that we can use multithreading to replace multiple processes and implement concurrent servers, which provides us with the advantage of developing fast commercial versions of chat rooms.
It is worth noting that in Linux, Java does not implement true multithreading and is essentially a multi-process.
◆ Post and get
Two common types of form information are submitted: post or get. Since the length of a post is unrestricted, it is used as a method for most form submissions. The get method sends the submitted information through the URL. Because the URL is limited by the length of the WWW server, the maximum length is generally 1024 bytes. Therefore, if the sent information is too long, this method cannot be used.
Because we have a limit on the length of the chat content, it will not be too long, and the get method is used for common page browsing. Using the get method to submit a form can simplify the process, therefore, we can use this method to submit chat content.
What we feel is that the get method simply attaches the submitted content to the end of the connection. If we can encode the submitted content in HTML, we can make the customer more comfortable.
◆ Use Java to implement concurrent socket communication
If you have done c socket programming before, this section will not be difficult for you. Using Java's multithreading mechanism, we can easily implement concurrent services.
Whenever we know that the server master program creates a new socket connection (that is, the accept () method is successfully called, start a new thread to take charge of the connection between the server and the customer. The main program will return and wait for the next connection. To achieve this scheme, the main cycle of the server should adopt the following form:
While (true)
{Socket newjoin = S. Accept ();
Tread T = new threadedchathandle (newjoin );
T. Start ();
}
The threadedchathandle class is a subclass of the chat processing process derived from the Thread class. Its run () this includes communication cycles between servers and customers-determining customer requests (such as logon, speaking, and refreshing the online list), processing speech data, and sending chat information. The following is an example of a server program that helps beginners understand as soon as possible.
Import java. Io .*;
Import java.net .*;
Public class chatserver
{Public static void main (string [] ARGs)
{Int I = 1;
Try
{Serversocket S = new serversocket (8080 );
/* Create a server socket for monitoring port 8080. If necessary, you can change it to port 80 */
For (;;)
{Socket newjoin = S. Accept ();
/* Wait for a connection. If the connection is not created, this method blocks the current thread. The returned value is
Socket object. The server program can use this object to communicate with connected customers. */
System. Out. println ("New Connection" + I );
New threadedchathandle (newjoin, I). Start ();
/* Threadedchathandle (socket thes, int C) is our own chat service class.
Class is further described later */
I ++;
}
}
Catch (exception E)
{System. Out. println (E );
}
}
......
}
A key issue of multi-process (thread) Concurrent services is how to implement inter-process (thread) communication. Each customer's speech (including expressions and actions) needs to be put in a public place so that all output threads can obtain it. There are many solutions, such as storing them in a database, in a dat file that everyone has permissions, or directly using pipelines to implement inter-process communication. For a chat room server, the first method is the most silly, which consumes too much system resources and slows down program execution efficiency, which may increase the number of errors. By using pipeline communication, all the speech data is stored in the memory, which not only achieves the highest execution efficiency, but also ensures a secure execution process, and does not need to consider thread synchronization issues. Don't think that there will be a lot of data for all the speeches. In fact, the server simply needs to save the last 100 sentences, isn't it?
APIS for pipelines in Java include:
● Java. Io. pipedinputstream
Pipldinputstream ():
Create a new pipeline input stream, and it is not associated with a pipeline output stream.
Pipldinputstream (pipldoutputstream out ):
Create a new pipeline input stream and read data from the pipeline output stream.
Connect (pipldoutputstream out ):
Associate the output stream of an MPS queue and read the data.
● Java. Io. pipedoutputstream
Pipldoutputstream ():
Create a new mps queue output stream, and it is not associated with an MPS queue input stream.
Pipldoutputstream (pipldinputstream in ):
Create a new pipeline output stream and output data to in.
Connect (pipldinputstream in ):
Associate an input stream of an MPS queue and input data to in.
◆ Daemon implementation
In fact, I have not found a method to implement the background daemon directly in Java. To implement a background process, you need to complete a series of tasks, including disabling all file descriptions, changing the current working directory, resetting the file access shield code (umask), and executing it in the background; disconnects from the process group, ignores terminal I/O signals, and disconnects from the control terminal.
There is a daemon thread in Java that I have never used. According to reports, the only purpose of this kind of service thread is to provide services for other threads. If only the service thread is left in a program, the program will stop (just like our original intention ). If you are interested, you can check the related content in Java. Lang. thread. setdaemon ().
Although we cannot use Java to implement backend service daemon, we still have Java C interfaces and there are always solutions to the problem.
◆ Exception Handling
In the socket communication process, exceptions may occur. If data is directly sent without processing, the program may exit unexpectedly. For example, the server continues to send data after the customer closes the socket, which may cause exceptions. To avoid this situation, we must process it. In general, we only need to simply ignore this signal. Fortunately, Java's exception handling mechanism is still strong.
◆ User disconnection judgment and handling
In many cases, the user does not leave the chat room by submitting the "leave" button. In this case, you need to determine whether the user is disconnected. Generally, user disconnection may include the following situations: when the user closes the browser, clicks the stop button of the browser, or jumps to another webpage (if a chat window pops up with JavaScript, we can avoid these two cases-right-click is not a big deal), the corresponding socket will become readable, and the data read at this time is a null string.
With this principle, as long as a readable socket reads data but reads NULL data, we can conclude that the user corresponding to this socket is disconnected.
◆ Prevent connection timeout and disconnection
If the browser does not receive any data within a period of time, a timeout error occurs. To avoid this error, you must send some data at a certain interval. In our application system, you can send some HTML comments. The process of sending comments can be directly inserted between chat content.