Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package chat.com.server; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.HashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JOptionPane; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; /** * * @author anhnghiammk */ public class ChatServer extends javax.swing.JFrame { private ServerSocket serSocket; private InputStreamReader inReader; private BufferedReader buffReader; private PrintWriter writer; private HashMap<String, PrintWriter> map; private String id = null; private ExecutorService exec; public ChatServer() { initComponents(); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { jScrollPane1 = new javax.swing.JScrollPane(); jTextAreaChat = new javax.swing.JTextArea(); jButtonStart = new javax.swing.JButton(); jButtonEnd = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setResizable(false); jTextAreaChat.setColumns(20); jTextAreaChat.setFont(new java.awt.Font("Consolas", 0, 13)); // NOI18N jTextAreaChat.setRows(5); jScrollPane1.setViewportView(jTextAreaChat); jButtonStart.setText("Start"); jButtonStart.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButtonStartActionPerformed(evt); } }); jButtonEnd.setText("End"); jButtonEnd.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButtonEndActionPerformed(evt); } }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup().addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane1) .addGroup(layout.createSequentialGroup() .addComponent(jButtonStart, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 320, Short.MAX_VALUE) .addComponent(jButtonEnd, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap())); layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup().addContainerGap() .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 240, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jButtonStart, javax.swing.GroupLayout.DEFAULT_SIZE, 33, Short.MAX_VALUE) .addComponent(jButtonEnd, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addGap(24, 24, 24))); pack(); }// </editor-fold> private void jButtonStartActionPerformed(java.awt.event.ActionEvent evt) { exec = Executors.newFixedThreadPool(50); exec.execute(new ThreadServer()); jTextAreaChat.append("Server start....." + '\n'); } private void jButtonEndActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: System.exit(0); } protected class ThreadServer implements Runnable { @Override public void run() { try { ServerSocket serSocket = new ServerSocket(2222); map = new HashMap<>(); while (true) { exec.execute(new ThreadClient(serSocket.accept())); } } catch (IOException ex) { Logger.getLogger(ChatServer.class.getName()).log(Level.SEVERE, null, ex); } } } protected class ThreadClient implements Runnable { protected Socket me; public ThreadClient(Socket me) { this.me = me; } @Override public void run() { try { Socket socket = me; InputStreamReader inReader = new InputStreamReader(socket.getInputStream()); BufferedReader buffReader = new BufferedReader(inReader); PrintWriter writer = new PrintWriter(socket.getOutputStream()); JSONObject jsonID = new JSONObject(); id = "p" + (System.nanoTime() % 10000); // create id jsonID.put("id", id); jsonID.put("type", "me"); String json = jsonID.toJSONString(); writer.println(json); // send id to user writer.flush(); map.put(id, writer); updateUserOnline(); jTextAreaChat.append(id + " joined...." + '\n'); Thread thread = new Thread(new Runnable() { @Override public void run() { try { String msg = null; while ((msg = buffReader.readLine()) != null) { System.out.println(msg); typeChat(msg); } } catch (IOException ex) { Logger.getLogger(ChatServer.class.getName()).log(Level.SEVERE, null, ex); // someQuit(id); } } }); thread.start(); } catch (IOException ex) { Logger.getLogger(ChatServer.class.getName()).log(Level.SEVERE, null, ex); } } } private void typeChat(String msg) { try { JSONParser jsonParser = new JSONParser(); JSONObject jsonTypeChat = (JSONObject) jsonParser.parse(msg); String type = jsonTypeChat.get("type").toString(); if (type.equals("clientout")) { String idClientOut = jsonTypeChat.get("id").toString(); someQuit(idClientOut); } else { // send message String to = jsonTypeChat.get("to").toString(); String id = jsonTypeChat.get("id").toString(); if (!to.equals("all")) { PrintWriter writer = map.get(to); writer.println(msg); writer.flush(); jTextAreaChat.append(msg + '\n'); } else { for (String key : map.keySet()) { if (!id.equals(key)) { // send message to all PrintWriter writer = map.get(key); writer.println(msg); writer.flush(); jTextAreaChat.append(msg + '\n'); } } } } } catch (ParseException ex) { Logger.getLogger(ChatServer.class.getName()).log(Level.SEVERE, null, ex); } } private void updateUserOnline() { int s = map.size(); JSONArray arr = new JSONArray(); for (String key : map.keySet()) { // add user online arr.add(key); } JSONObject jsonUpdateUser = new JSONObject(); jsonUpdateUser.put("type", "userOnline"); jsonUpdateUser.put("listUser", arr); String json = jsonUpdateUser.toString(); for (String key : map.keySet()) { // send message to all PrintWriter writer = map.get(key); writer.println(json); writer.flush(); } } private void someQuit(String id) { map.remove(id); jTextAreaChat.append(id + " out" + '\n'); updateUserOnline(); } /** * @param args the command line arguments */ public static void main(String args[]) { /* Set the Nimbus look and feel */ //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Metal".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { java.util.logging.Logger.getLogger(ChatServer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(ChatServer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(ChatServer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(ChatServer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); } //</editor-fold> /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new ChatServer().setVisible(true); } }); } // Variables declaration - do not modify private javax.swing.JButton jButtonEnd; private javax.swing.JButton jButtonStart; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTextArea jTextAreaChat; // End of variables declaration }