Java Socket Chat Room Programming Using Sockets to Implement Single Chat Room

Keywords: Java socket Database Programming

This article mainly introduces Java Socket chat room programming (2) Using sockets to achieve single chat room related materials, very good, has reference value, the friends you need can refer to

In the previous article, Java Socket Chat Room Programming (1) Using sockets to push chat messages, we talked about how to use sockets to get messages between the server and the client so that they can be pushed. Next, I will write how to get the server to establish communication between the client and the client.

In fact, it is to establish a one-to-one chat communication.

Unlike the previous code that implemented message push, it was modified on top of it.

If no methods or classes are mentioned, they are identical to the previous one.

1, Modify entity classes (server-side and client-side entity classes are the same)

1, UserInfoBean User Information Table

public class UserInfoBean implements Serializable {
private static final long serialVersionUID = 2L;
private long userId;//User id
private String userName;//User name
private String likeName;//Nickname
private String userPwd;//User password
private String userIcon;//User Avatar
//Omit get, set methods
}

2, MessageBean Chat Information Table

public class MessageBean implements Serializable {
private static final long serialVersionUID = 1L;
private long messageId;//Message id
private long groupId;//Group id
private boolean isGoup;//Is it a group message?
private int chatType;//Message Type; 1, Text; 2, Picture; 3, Small Video; 4, File; 5, Geographic Location; 6, Voice; 7, Video Call
private String content;//Text message content
private String errorMsg;//Error message
private int errorCode;//Error Code
private int userId;//User id
private int friendId;//Target Friend id
private MessageFileBean chatFile;//Message Attachment
//Omit get, set methods
}

3, MessageFileBean message attachment table

public class MessageFileBean implements Serializable {
private static final long serialVersionUID = 3L;
private int fileId;//file id
private String fileName;//File Name
private long fileLength;//file length
private Byte[] fileByte;//File Content
private String fileType;//file type
private String fileTitle;//File Header Name
//Omit get, set methods
}

2, (Server-side code modification) ChatServer's main chat service class, to modify

public class ChatServer {
//socket Service
private static ServerSocket server;
//Use ArrayList to store all Socket s
public List<Socket> socketList = new ArrayList<>();
//Imitate socket s stored in memory
public Map<Integer, Socket> socketMap = new HashMap();
//Imitate user information stored in the database
public Map<Integer, UserInfoBean> userMap = new HashMap();
public Gson gson = new Gson();
/**
* Initialize socket service
*/
public void initServer() {
try {
//Create a ServerSocket to listen for client requests on port 8080
server = new ServerSocket(SocketUrls.PORT);
createMessage();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Create message management and receive messages all the time
*/
private void createMessage() {
try {
System.out.println("Waiting for user access : ");
//Use accept() to block waiting for customer requests
Socket socket = server.accept();
//Save the linked socket in the collection
socketList.add(socket);
System.out.println("User Access : " + socket.getPort());
//Open a sub-thread to wait for another socket to join
new Thread(new Runnable() {
public void run() {
//Create a socket service again waiting for other users to access
createMessage();
}
}).start();
//Used by server to push messages to users
getMessage();
//Get information from the client
BufferedReader bff = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//Read incoming server information
String line = null;
//Loop keeps receiving messages from the current socket
while (true) {
Thread.sleep(500);
//System.out.println("Content:"+ bff.readLine()));
//Get client information
while ((line = bff.readLine()) != null) {
//Resolve Entity Classes
MessageBean messageBean = gson.fromJson(line, MessageBean.class);
//Add user information to the map, mimic adding to database and memory
//Entity classes are stored in the database, socket s are stored in memory, and user IDs are used as references
setChatMap(messageBean, socket);
//Forward incoming messages to target friends
getFriend(messageBean);
System.out.println("user : " + userMap.get(messageBean.getUserId()).getUserName());
System.out.println("content : " + messageBean.getContent());
}
}
// server.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("error : " + e.getMessage());
}
}
/**
* send message
*/
private void getMessage() {
new Thread(new Runnable() {
public void run() {
try {
String buffer;
while (true) {
//Enter from console
BufferedReader strin = new BufferedReader(new InputStreamReader(System.in));
buffer = strin.readLine();
//Because readLine ends with a line break, a line break is added at the end
buffer += "
";
//Modified here to push messages to all users connected to the server
for (Socket socket : socketMap.values()) {
OutputStream output = socket.getOutputStream();
output.write(buffer.getBytes("utf-8"));
//Send data
output.flush();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
/**
* Simulate adding information into database and memory
*
* @param messageBean
* @param scoket
*/
private void setChatMap(MessageBean messageBean, Socket scoket) {
//Save user information
if (userMap != null && userMap.get(messageBean.getUserId()) == null) {
userMap.put(messageBean.getUserId(), getUserInfoBean(messageBean.getUserId()));
}
//Save the socket with the corresponding link in
if (socketMap != null && socketMap.get(messageBean.getUserId()) == null) {
socketMap.put(messageBean.getUserId(), scoket);
}
}
/**
* Simulate user information for the database, where user information with different IDS is created
*
* @param userId
* @return
*/
private UserInfoBean getUserInfoBean(int userId) {
UserInfoBean userInfoBean = new UserInfoBean();
userInfoBean.setUserIcon("User Portrait");
userInfoBean.setUserId(userId);
userInfoBean.setUserName("admin");
userInfoBean.setUserPwd("123123132a");
return userInfoBean;
}
/**
* Forward message to target friend
*
* @param messageBean
*/
private void getFriend(MessageBean messageBean) {
if (socketMap != null && socketMap.get(messageBean.getFriendId()) != null) {
Socket socket = socketMap.get(messageBean.getFriendId());
String buffer = gson.toJson(messageBean);
//Because readLine ends with a line break, a line break is added at the end
buffer += "
";
try {
//Send information to client
OutputStream output = socket.getOutputStream();
output.write(buffer.getBytes("utf-8"));
//Send data
output.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

3, (Client Code) LoginActivity login page modification allows multiple logins

public class LoginActivity extends AppCompatActivity {
private EditText chat_name_text, chat_pwd_text;
private Button chat_login_btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
chat_name_text = (EditText) findViewById(R.id.chat_name_text);
chat_pwd_text = (EditText) findViewById(R.id.chat_pwd_text);
chat_login_btn = (Button) findViewById(R.id.chat_login_btn);
chat_login_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int status = getLogin(chat_name_text.getText().toString().trim(), chat_pwd_text.getText().toString().trim());
if (status == -1 || status == 0) {
Toast.makeText(LoginActivity.this, "Password error", Toast.LENGTH_LONG).show();
return;
}
getChatServer(getLogin(chat_name_text.getText().toString().trim(), chat_pwd_text.getText().toString().trim()));
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
});
}
/**
* Return to login status, 1 for user and 2 for another user, where two users are simulated communicating with each other
*
* @param name
* @param pwd
* @return
*/
private int getLogin(String name, String pwd) {
if (TextUtils.isEmpty(name) || TextUtils.isEmpty(pwd)) {
return 0;//No full password was entered
} else if (name.equals("admin") && pwd.equals("1")) {
return 1;//User 1
} else if (name.equals("admin") && pwd.equals("2")) {
return 2;//User 2
} else {
return -1;//Password error
}
}
/**
* Instantiate a chat service
*
* @param status
*/
private void getChatServer(int status) {
ChatAppliaction.chatServer = new ChatServer(status);
}
}

4, (Client Code) Modification of ChatServer Chat Service Code Logic

public class ChatServer {
private Socket socket;
private Handler handler;
private MessageBean messageBean;
private Gson gson = new Gson();
//Obtain output stream from Socket object and construct PrintWriter object
PrintWriter printWriter;
InputStream input;
OutputStream output;
DataOutputStream dataOutputStream;
public ChatServer(int status) {
initMessage(status);
initChatServer();
}
/**
* Message Queue, used to deliver messages
*
* @param handler
*/
public void setChatHandler(Handler handler) {
this.handler = handler;
}
private void initChatServer() {
//Start Thread to Receive Messages
receiveMessage();
}
/**
* Initialize user information
*/
private void initMessage(int status) {
messageBean = new MessageBean();
UserInfoBean userInfoBean = new UserInfoBean();
userInfoBean.setUserId(2);
messageBean.setMessageId(1);
messageBean.setChatType(1);
userInfoBean.setUserName("admin");
userInfoBean.setUserPwd("123123123a");
//The following action mimics saving the user id and the chat target user id when the user clicks on a friend's expanded chat interface
if (status == 1) {//If User 1, he chats to User 2
messageBean.setUserId(1);
messageBean.setFriendId(2);
} else if (status == 2) {//If User 2, he chats to User 1
messageBean.setUserId(2);
messageBean.setFriendId(1);
}
ChatAppliaction.userInfoBean = userInfoBean;
}
/**
* send message
*
* @param contentMsg
*/
public void sendMessage(String contentMsg) {
try {
if (socket == null) {
Message message = handler.obtainMessage();
message.what = 1;
message.obj = "The server is down";
handler.sendMessage(message);
return;
}
byte[] str = contentMsg.getBytes("utf-8");//Convert content to utf-8
String aaa = new String(str);
messageBean.setContent(aaa);
String messageJson = gson.toJson(messageBean);
/**
* Because readLine() on the server side is blocking reads
* If it can't read a line break or the end of the output stream will always be blocked there
* So put a line break at the end of the json message to tell the server that the message has been sent
* */
messageJson += "
";
output.write(messageJson.getBytes("utf-8"));//Line Break Printing
output.flush(); //Refresh the output stream so that Server receives the string immediately
} catch (Exception e) {
e.printStackTrace();
Log.e("test", "Error:" + e.toString());
}
}
/**
* Receive messages, in subthreads
*/
private void receiveMessage() {
new Thread(new Runnable() {
@Override
public void run() {
try {
//Make a client request to port 8080 of this machine
socket = new Socket(SocketUrls.IP, SocketUrls.PORT);
//Get input stream from Socket object and construct corresponding BufferedReader object
printWriter = new PrintWriter(socket.getOutputStream());
input = socket.getInputStream();
output = socket.getOutputStream();
dataOutputStream = new DataOutputStream(socket.getOutputStream());
//Get information from the client
BufferedReader bff = new BufferedReader(new InputStreamReader(input));
//Read incoming server information
String line;
while (true) {
Thread.sleep(500);
//Get client information
while ((line = bff.readLine()) != null) {
Log.i("socket", "content : " + line);
MessageBean messageBean = gson.fromJson(line, MessageBean.class);
Message message = handler.obtainMessage();
message.obj = messageBean.getContent();
message.what = 1;
handler.sendMessage(message);
}
if (socket == null)
break;
}
output.close();//Close Socket Output Stream
input.close();//Close Socket Input Stream
socket.close();//Close Socket
} catch (Exception e) {
e.printStackTrace();
Log.e("test", "Error:" + e.toString());
}
}
}).start();
}
public Socket getSocekt() {
if (socket == null) return null;
return socket;
}
}

As a result, code logic has changed from message pushing logic to chatting logic.

This code allows users 1 and 2 to chat with each other, and the server records the chat between them.The server also has the ability to push messages.

The above is the Java Socket Chat Room Programming (2) which is introduced by Xiaobian. It uses sockets to realize chat room. I hope it will be helpful to you. If you have any questions, please leave a message for me.

"We believe that everyone can become a java development god. Now, find a buddy to take you to the beginning and stop being confused on your way to study.This is a java development seminar where beginners move to the Internet industry."

I have been developing for more than 10 years. If you have questions about how to learn java, the learning route and whether you don't know whether you should study or train yourself, you can always ask me. You can add my java to exchange learning qun:615741636.There are learning tutorials and development tools within qun.

Posted by bedrosamo on Thu, 09 May 2019 17:50:39 -0700