The message push function completed by websocket and Java is used by the server tomcat7.0. Some things are considered by yourself, and I don’t know if they are appropriate or inappropriate. Please forgive me and point them out.
In simple terms, customer A can send messages to customer B, but there are many places that can be expanded.
for example
1. If after joining the database, when A sends the message, customer B is not online, the server will store the message in the database. After customer B is online, the message will be retrieved and sent to customer B.
2. The server can also send messages to any client.
The screenshot of the program's running effect is as follows (tested under chrome, Sogou, and firefox): the code will be given at the end
First, we open a browser and display to enter your name. Here I enter soar
When opening the second browser, here I enter bill
This is if I send hello bill i am soar to bill, click send
You can see it on another browser
Websocket
1.What is websocket?
WebSocket is a technology that is generated to solve real-time communication between clients and servers. The essence is to create a TCP connection for exchanging data after handshaking through HTTP/HTTPS protocol.
After that, the server and the client communicate in real time through this TCP connection.
2. Advantages of websocket
In the past, we implemented push technology, using polling. At the characteristic time interval, the browser automatically issues a request and actively pulls back the server's messages. In this case, we need to constantly send requests to the server. However, the header of the HTTP request is very long, and the data contained in it may be just a small value, which will occupy a lot of bandwidth and server resources. It will consume a lot of bandwidth and server resources.
The greatest thing about the WebSocket API is that the server and client can push information to each other at any time within a given time range. After establishing the connection, the server can actively transmit data to the client.
In addition, the header information exchanged between the server and the client is very small.
WebSocket is not limited to communication in Ajax (or XHR) mode, because Ajax technology requires clients to initiate requests, while WebSocket servers and clients can push information to each other;
For a detailed introduction to ajax, comet, websocket and websocket messages, you can refer to http://www.shaoqun.com/a/54588.aspx web design]Ajax, Comet and Websocket.
If I have time in the future, I will write it out.
3. How to use websocket
Client
In a browser that supports WebSocket, after creating the socket. You can respond to sockets through four events: onopen, onmessage, and onclose, that is, onerror.
A simple example
var ws = new WebSocket(ws://localhost:8080);ws.onopen = function(){ console.log(open); ws.send(hello);};ws.onmessage = function(evt){ console.log(evt.data)};ws.onclose = function(evt){ console.log(WebSocketClosed!);};ws.onerror = function(evt){ console.log(WebSocketError!);};1.var ws = new WebSocket(ws://localhost:8080);
To apply for a WebSocket object, the parameters are the address of the server that needs to be connected. Just like the http protocol, the URL of the WebSocket protocol starts with ws://, and the secure WebSocket protocol starts with wss://.
ws.send(hello);
Used to send messages to the server
2.ws.onopen = function() { console.log(open)};
When the websocket is created successfully, the onopen event will be triggered
3.ws.onmessage = function(evt) { console.log(evt.data) };
When the client receives a message sent by the server, the onmessage event will be triggered. The parameter evt.data contains the data transmitted by the server.
4.ws.onclose = function(evt) { console.log(WebSocketClosed!); };
When the client receives a request to close the connection sent by the server, the onclose event is triggered
5.ws.onerror = function(evt) { console.log(WebSocketError!); };
If connection, processing, receiving, and sending data fail, onerror event will be triggered
We can see that all operations are triggered by events, so that the UI will not block, allowing the UI to have faster response time and a better user experience.
Server side
Nowadays, there are many server software that supports websocket, such as node.js, jetty, tomcat, etc.
Here I am using tomat 7.0 and eclipse4.2
Tomcat, use websocket first to import the relevant jar
The classes related to WebSocket provided by tomcat7 are all located in the package org.apache.catalina.websocket (the implementation of package org.apache.catalina.websocket is contained in the file catalina.jar
Here we just import all tomcat
In build path->configure build path->librarise->add library->server runtime->apache tomcat v7.0
image
Also, import the following packages
import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WsOutbound;
import org.apache.catalina.websocket.WebSocketServlet;
We need two classes
The first one is used to handle websocket requests
The second one is used to handle each specific WebSocket task
The first category
public class SocketServer extends WebSocketServlet {
private static final long serialVersionUID = 1L;
//…
@Override
protected StreamInbound createWebSocketInbound(String arg0,
HttpServletRequest arg1) {
// TODO Auto-generated method stub
return new ChatWebSocket(users);
}
}
This Servlet inherits from WebSocketServlet and implements the createWebSocketInbound method. This method returns an instance of the second class.
The second category
public class ChatWebSocket extends MessageInbound {
@Override
protected void onTextMessage(CharBuffer message) throws IOException {
}
@Override
protected void onOpen(WsOutbound outbound) {
}
@Override
protected void onClose(int status) {
}
@Override
protected void onBinaryMessage(ByteBuffer arg0) throws IOException {
}
//The rest is just a little
}
protected void onTextMessage(CharBuffer message) throws IOException { }
Text message response
protected void onBinaryMessage(ByteBuffer arg0) throws IOException { }
Binary message response
protected void onOpen(WsOutbound outbound) { }
Events triggered by establishing a connection
protected void onClose(int status) { }
Events fired when closing the connection
4. Program code
html part
<!DOCTYPE HTML>
<html>
<head>
<meta charset=utf-8>
<script type=text/javascript src=js/jquery.js></script>
<script type=text/javascript src=js/socket.js></script>
<title>Unt titled document</title>
</head>
<script language=javascript>
</script>
<body>
<table>
<tr>
<td>Message</td>
<td><input type=text id=message></td>
</tr>
<tr>
<td>Name</td>
<td><input type=text id=othername></td>
</tr>
<tr>
<td><input id=sendbutton type=button value=send onClick=click disabled=true>
</input></td>
</tr>
</table>
<script>
</script>
</body>
</html>
js part (no explanation about jquery part)
var username = window.prompt(enter your name:);
document.write(Welcome<p id=/username/>+username+</p>);
if (!window.WebSocket && window.MozWebSocket)
window.WebSocket=window.MozWebSocket;
if (!window.WebSocket)
alert(No Support);
var ws;
$(document).ready(function(){
$(#sendbutton).attr(disabled, false);
$(#sendbutton).click(sendMessage);
startWebSocket();
})
function sendMessage()
{
var othername=$(#othername).val();
var msg=MSG/t+username+_+othername+_+$(#message).val();
send(msg);
}
function send(data)
{
console.log(Send:+data);
ws.send(data);
}
function startWebSocket()
{
ws = new WebSocket(ws:// + location.host + /WebSocket/SocketServer);
ws.onopen = function(){
console.log(success open);
$(#sendbutton).attr(disabled, false);
};
ws.onmessage = function(event)
{
console.log(RECEIVE:+event.data);
handleData(event.data);
};
ws.onclose = function(event) {
console.log(Client notified socket has closed,event);
};
}
function handleData(data)
{
var vals=data.split(/t);
var msgType=vals[0];
switch(msgType)
{
case NAME:
var msg=vals[1];
var mes=NAME+/t+msg+_+ username;
send(mes);
break;
case MSG:
var val2s=vals[1].split(_);
var from=val2s[0];
var message=val2s[2];
alert(from+:+message);
break;
default:
break;
}
}
Java part
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import javax.servlet.http.HttpServletRequest;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WsOutbound;
import org.apache.catalina.websocket.WebSocketServlet;
public class SocketServer extends WebSocketServlet {
private static final long serialVersionUID = 1L;
public final Set<ChatWebSocket> users = new CopyOnWriteArraySet<ChatWebSocket>();
public static int USERNUMBER = 1;
@Override
protected StreamInbound createWebSocketInbound(String arg0,
HttpServletRequest arg1) {
// TODO Auto-generated method stub
return new ChatWebSocket(users);
}
public class ChatWebSocket extends MessageInbound {
private String username;
private Set<ChatWebSocket> users = new CopyOnWriteArraySet<ChatWebSocket>();;
public ChatWebSocket() {
}
public ChatWebSocket(Set<ChatWebSocket> users) {
this.users = users;
}
@Override
protected void onTextMessage(CharBuffer message) throws IOException {
// What is processed here is text data
}
public void onMessage(String data) {
String[] val1 = data.split(//t);
if(val1[0].equals(NAME))
{
String[] val2=val1[1].split(_);
for(ChatWebSocket user:users){
if (user.username.equals(val2[0])){
user.username=val2[1];
}
}
}
else if(val1[0].equals(MSG))
{
String[] val2=val1[1].split(_);
for(ChatWebSocket user:users){
if (user.username.equals(val2[1])){
try {
CharBuffer temp=CharBuffer.wrap(data);
user.getWsOutbound().writeTextMessage(temp);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
else
{
System.out.println(ERROR);
}
}
@Override
protected void onOpen(WsOutbound outbound) {
// this.connection=connection;
this.username = # + String.valueOf(USERNUMBER);
USERNUMBER++;
try {
String message = NAME + /t + this.username;
CharBuffer buffer = CharBuffer.wrap(message);
this.getWsOutbound().writeTextMessage(buffer);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
users.add(this);
}
@Override
protected void onClose(int status) {
users.remove(this);
}
@Override
protected void onBinaryMessage(ByteBuffer arg0) throws IOException {
}
}
}
explain
My idea here is
1 When accessing, each user first needs to enter his or her name, and then send a connection request to the server.
2 After the server accepts the client's connection request, it will new ChatWebSocket(users); to process this request and add it to the online user list. At this time, the server does not yet know the customer's name. It will assume a name for this user, #1, and the server will send NAME + /t + #1 to the client, what are your name?
3 When the client receives this message, it will know that the server is asking itself what its name is, so the client will send NAME+/t+#1+_+ its own name to the server (my name is xxx)
4 After receiving this message, the server searches in the currently online user list based on #1, and replaces #1 with the customer's name, so that the server will know the customer's name.
5 When the customer leaves, the server will trigger the onClose event, and the server will remove the current user from the online list.
Use pictures to draw something like this (drawn badly, -_-!!)
Code
js
ws = new WebSocket(ws:// + location.host + /WebSocket/SocketServer);
Connect to the server
java
protected StreamInbound createWebSocketInbound(String arg0,
HttpServletRequest arg1) {
// TODO Auto-generated method stub
return new ChatWebSocket(users);
}
Create a chatwebsocket to handle this request and trigger the onOpen event of the chatwebsocket object
@Override
protected void onOpen(WsOutbound outbound) {
// this.connection=connection;
this.username = # + String.valueOf(USERNUMBER);
USERNUMBER++;
try {
String message = NAME + /t + this.username;
CharBuffer buffer = CharBuffer.wrap(message);
this.getWsOutbound().writeTextMessage(buffer);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
users.add(this);
}
Assuming a name for this client, sending the assumed name of NAME+/t+ to the client, and adding the client to the currently connected client list
js
function handleData(data)
{
var vals=data.split(/t);
var msgType=vals[0];
switch(msgType)
{
case NAME:
var msg=vals[1];
var mes=NAME+/t+msg+_+ username;
send(mes);
break;
//………
}
}
Accept and process the message sent by the server, and find that the server asked it what its name is, so it sent NAME+/t+the assumed name+_+ to the server.
java
public void onMessage(String data) {
String[] val1 = data.split(//t);
if(val1[0].equals(NAME))
{
String[] val2=val1[1].split(_);
for(ChatWebSocket user:users){
if (user.username.equals(val2[0])){
user.username=val2[1];
}
}
}
//………
}
Process and accept the message sent by the client, and find that the client replied to its name, so search in the currently connected client list based on the previously assumed name, and turn the pseudonym into the real name
js
function sendMessage()
{
var othername=$(#othername).val();
var msg=MSG/t+username+_+othername+_+$(#message).val();
send(msg);
}
The client initiates a conversation with another person, and the message format is: MSG+its own name+_+opposite name+_+message
java
public void onMessage(String data) {
///…………
else if(val1[0].equals(MSG))
{
String[] val2=val1[1].split(_);
for(ChatWebSocket user:users){
if (user.username.equals(val2[1])){
try {
CharBuffer temp=CharBuffer.wrap(data);
user.getWsOutbound().writeTextMessage(temp);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
///…………
}
It is found that the message is sent by the customer. According to the other party's name, search in the currently connected customer list and send the message to him.
js
function handleData(data)
{
var vals=data.split(/t);
var msgType=vals[0];
switch(msgType)
{
///…
case MSG:
var val2s=vals[1].split(_);
var from=val2s[0];
var message=val2s[2];
alert(from+:+message);
break;
default:
break;
}
}
It was found that it was a message sent by another customer, and it was displayed through alert
java
@Override
protected void onClose(int status) {
users.remove(this);
}
Discovering the customer has left, remove the customer from the connected customer list
Where to improve
1. If client A sends a message to B and B is not online, the message can be stored in the database. When B is found to be online, it will be retrieved from the database and sent to B.
2 When the server sends your name, it can add a timeout mechanism. If the client does not reply to what it is called within a certain period of time, the client can delete the client from the online list.