diff --git a/.vscode/launch.json b/.vscode/launch.json index fd70916..9f34117 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,6 +6,20 @@ "configurations": [ { "type": "java", + "name": "SimpleWebSocketServer", + "request": "launch", + "mainClass": "info.istlab.ServerTester.SimpleWebSocketServer", + "projectName": "ServerTester" + }, + { + "type": "java", + "name": "SimpleWebSocketServer", + "request": "launch", + "mainClass": "info.istlab.ServerTester.test.SimpleWebSocketServer", + "projectName": "ServerTester" + }, + { + "type": "java", "name": "WebSocketServer", "request": "launch", "mainClass": "info.istlab.ServerTester.WebSocketServer", diff --git a/pom.xml b/pom.xml index d8345f0..3475725 100644 --- a/pom.xml +++ b/pom.xml @@ -32,11 +32,11 @@ test - + diff --git a/src/main/java/info/istlab/ServerTester/AddPanel.java b/src/main/java/info/istlab/ServerTester/AddPanel.java index 6b7f8a4..a15efa2 100644 --- a/src/main/java/info/istlab/ServerTester/AddPanel.java +++ b/src/main/java/info/istlab/ServerTester/AddPanel.java @@ -26,7 +26,7 @@ host = _host; String[] options = { "WebServer", "TimeServer", "ThreadTimeServer", "EchoServer", "ThreadEchoServer", - "WhiteBoardServer" }; + "WhiteBoardServer", "SimpleWebSocketServer" }; servBox = new JComboBox(options); add(servBox); @@ -34,7 +34,7 @@ SpinnerNumberModel model = new SpinnerNumberModel(8081, 1024, 65535, 1); // 初期値、最小値、最大値、ステップ portSpinner = new JSpinner(model); JSpinner.NumberEditor editor = new JSpinner.NumberEditor(portSpinner, "#"); - NumberFormatter format = (NumberFormatter)editor.getTextField().getFormatter(); + NumberFormatter format = (NumberFormatter) editor.getTextField().getFormatter(); format.setAllowsInvalid(false); format.setCommitsOnValidEdit(true); portSpinner.setEditor(editor); @@ -60,9 +60,15 @@ System.out.println(portLong); int port = (int) portLong; String bindaddress = (String) bindBox.getSelectedItem(); - Server server = (Server) Class.forName("info.istlab.ServerTester." + className) - .getConstructor(int.class, String.class).newInstance(port, bindaddress); - host.addPanel(new ServerPanel(server, host)); + if (className.equals("SimpleWebSocketServer")) { + SimpleWebSocketServer wsserver = new SimpleWebSocketServer(port, bindaddress); + host.addPanel(new ServerPanel4WS(wsserver, host)); + return; + } else { + Server server = (Server) Class.forName("info.istlab.ServerTester." + className) + .getConstructor(int.class, String.class).newInstance(port, bindaddress); + host.addPanel(new ServerPanel(server, host)); + } } catch (Exception e1) { e1.printStackTrace(); } diff --git a/src/main/java/info/istlab/ServerTester/ServerPanel4WS.java b/src/main/java/info/istlab/ServerTester/ServerPanel4WS.java new file mode 100644 index 0000000..87e07f7 --- /dev/null +++ b/src/main/java/info/istlab/ServerTester/ServerPanel4WS.java @@ -0,0 +1,173 @@ +package info.istlab.ServerTester; + +import java.awt.Color; +import java.awt.Desktop; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; + +public class ServerPanel4WS extends JPanel implements Runnable { + + Host host; + SimpleWebSocketServer server; + String name; + + JLabel portLabel; + JLabel addressLabel; + JLabel statusLabel; + JButton stopButton; + Thread thread; + JButton delButton; + JButton clientButton; + + /** + * Create the panel. + */ + public ServerPanel4WS(SimpleWebSocketServer _server, Host _host) { + server = _server; + host = _host; + name = _server.getClass().getName(); + // remove package name + name = name.substring(name.lastIndexOf('.') + 1); + + JLabel lblNewLabel = new JLabel(name); + + add(lblNewLabel); + + portLabel = new JLabel(); + add(portLabel); + addressLabel = new JLabel(); + add(addressLabel); + statusLabel = new JLabel(); + add(statusLabel); + + stopButton = new JButton("Start"); + add(stopButton); + stopButton.addActionListener(e -> { + if (server.isClosed()) { + server.start(); + } else { + try { + server.stop(); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + } + repaint(); + host.pack(); + }); + + delButton = new JButton("Delete"); + delButton.setEnabled(false); + delButton.addActionListener(e -> { + try { + server.stop(); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + Host.mainhost.mainPanel.remove(this); + Host.mainhost.pack(); + }); + add(delButton); + + clientButton = new JButton("Client"); + add(clientButton); + clientButton.addActionListener(e -> { + if (name.startsWith("Web")) { + // open web browser + Desktop desktop = Desktop.getDesktop(); + try { + desktop.browse(new URI("http://" + server.getBindAddress() + ":" + server.getPort())); + } catch (IOException | URISyntaxException e1) { + } + } else if (name.startsWith("Echo") || name.startsWith("ThreadEcho")) { + new JExecutor("EchoClient", server.getPort() + " " + server.getBindAddress()); + // new EchoClient(server.getPort(), server.getBindAddress()); + } else if (name.startsWith("Time") || name.startsWith("ThreadTime")) { + new JExecutor("TimeClient", server.getPort() + " " + server.getBindAddress()); + // new TimeClient(server.getPort(), server.getBindAddress()); + } else if (name.startsWith("WhiteBoard")) { + new JExecutor("WhiteBoardClient", server.getPort() + " " + server.getBindAddress()); + // new WhiteBoardClient(server.getPort(), server.getBindAddress()); + } + }); + thread = new Thread(this); + thread.start(); + } + + @Override + public void run() { + while (thread != null) { + if (server.isClosed()) { + portLabel.setText(String.valueOf(server.getExpectedPort())); + addressLabel.setText(server.getExpectedAddress()); + if (server.bindFailed) { + statusLabel.setText("Closed (Bind失敗)"); + } else { + statusLabel.setText("Closed"); + } + stopButton.setText("Restart"); + delButton.setEnabled(true); + clientButton.setEnabled(false); + } else { + portLabel.setText(String.valueOf(server.getExpectedPort())); + addressLabel.setText(server.getExpectedAddress()); + statusLabel.setText("Running"); + stopButton.setText("Stop"); + delButton.setEnabled(false); + clientButton.setEnabled(true); + } + + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public void paintComponent(Graphics g) { + super.paintComponent(g); + Color color1 = Color.yellow; + Color color2 = Color.orange; + if (server.isClosed()) { + + } else { + color1 = Color.cyan; + color2 = new Color(100, 100, 255); + } + + // Graphics2D オブジェクトを取得 + Graphics2D g2d = (Graphics2D) g; + + // パネルの幅と高さを取得 + int width = getWidth(); + int height = getHeight(); + + // グラデーションを設定(左上から右下にかけて) + GradientPaint gradientPaint = new GradientPaint(width / 4, 0, color1, width, height, color2); + + // グラデーションで塗りつぶす + g2d.setPaint(gradientPaint); + g2d.fillRect(0, 0, width, height); + + g2d.setColor(Color.lightGray); + g2d.drawRect(0, 0, width - 1, height - 1); + + } + + public String getAvailableServices() { + if (!server.isClosed()) { + return name + " " + server.getExpectedPort() + " " + server.getExpectedAddress() + " Running"; + } else { + return name + " " + server.getExpectedPort() + " " + server.getExpectedAddress() + " Closed"; + } + } +} diff --git a/src/main/java/info/istlab/ServerTester/SimpleWebSocketServer.java b/src/main/java/info/istlab/ServerTester/SimpleWebSocketServer.java new file mode 100644 index 0000000..108943e --- /dev/null +++ b/src/main/java/info/istlab/ServerTester/SimpleWebSocketServer.java @@ -0,0 +1,95 @@ +package info.istlab.ServerTester; + +import java.net.InetSocketAddress; +import java.util.Collection; + +import org.java_websocket.WebSocket; +import org.java_websocket.handshake.ClientHandshake; +import org.java_websocket.server.WebSocketServer; + +public class SimpleWebSocketServer extends WebSocketServer { + + public static void main(String[] args) { + Server.invokeMain(args, "SimpleWebSocketServer"); + } + + int expectedPort; + String expectedAddress; + boolean bindFailed = false; + boolean isClosed = false; + public SimpleWebSocketServer() { + this(8887, "0.0.0.0"); + } + + public SimpleWebSocketServer(int port) { + this(port, "0.0.0.0"); + } + + public SimpleWebSocketServer(int port, String bindaddress) { + super(new InetSocketAddress(bindaddress, port)); + expectedPort = port; + expectedAddress = bindaddress; + start(); + System.out.println("WebSocket server started on port: " + port + " " + bindaddress); + } + + @Override + public void onOpen(WebSocket conn, ClientHandshake handshake) { + System.out.println("New connection from " + conn.getRemoteSocketAddress()); + conn.send("Welcome to the server! " + conn.getRemoteSocketAddress()); // クライアントにメッセージを送信 + } + + @Override + public void onClose(WebSocket conn, int code, String reason, boolean remote) { + System.out.println("Closed connection to " + conn.getRemoteSocketAddress()); + isClosed = true; + } + + @Override + public void onMessage(WebSocket conn, String message) { + System.out.println("Received: " + message); + // conn.send("Echo: " + message); // 受け取ったメッセージをそのまま返す + broadcastMessage(message); // すべてのクライアントにメッセージを送信 + } + + @Override + public void onError(WebSocket conn, Exception ex) { + System.out.println("Error: " + ex.getMessage()); + if (ex.getMessage().startsWith("Address already in use")){ + bindFailed = true; + isClosed = true; + } + } + + @Override + public void onStart() { + System.out.println("Server started successfully"); + isClosed = false; + } + + // 全クライアントにメッセージをブロードキャストするメソッド + private void broadcastMessage(String message) { + Collection clients = this.getConnections(); + for (WebSocket client : clients) { + if (client.isOpen()) { + client.send(message); + } + } + } + + public String getBindAddress() { + return expectedAddress; + } + + public boolean isClosed() { + return isClosed; + } + + public String getExpectedAddress() { + return expectedAddress; + } + + public int getExpectedPort() { + return expectedPort; + } +} diff --git a/wschat.html b/wschat.html new file mode 100644 index 0000000..604cf4e --- /dev/null +++ b/wschat.html @@ -0,0 +1,66 @@ + + + + + + + WebSocket Test + + + +

WebSocket Client

+
+ + + +
+
+ + + + + \ No newline at end of file