This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>WebSocket Test</title> | |
<script type="text/javascript"> | |
var ws = new WebSocket("ws://localhost:5000"); | |
ws.onopen = function(){ | |
ws.send("test"); | |
console.log("open"); | |
} | |
ws.onerror = function(){ | |
console.log("error"); | |
} | |
ws.onclose = function(){ | |
console.log("close"); | |
} | |
ws.onmessage = function(msg) { | |
console.log("msg received:" + msg.data); | |
var log = document.getElementById("log"); | |
log.innerHTML += "msg received:" + msg.data; | |
}; | |
</script> | |
</head> | |
<body> | |
<h1>WebSocket Test</h1> | |
<div id="log"></div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.sanofc.ws; | |
import java.io.BufferedReader; | |
import java.io.IOException; | |
import java.io.InputStreamReader; | |
import java.io.OutputStreamWriter; | |
import java.io.PrintStream; | |
import java.net.ServerSocket; | |
import java.net.Socket; | |
import java.nio.ByteBuffer; | |
import java.nio.file.Files; | |
import java.nio.file.Path; | |
import java.nio.file.Paths; | |
import java.security.MessageDigest; | |
import java.security.NoSuchAlgorithmException; | |
import java.util.Base64; | |
import java.util.HashSet; | |
public class WebSocketServer { | |
private static HashSet<Socket> socketSet = new HashSet<Socket>(); | |
public static void main(String[] args) throws IOException { | |
int port = 5000; | |
ServerSocket serverSocket = new ServerSocket(port); | |
while (true) { | |
Socket socket = serverSocket.accept(); | |
System.out.println("accept"); | |
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); | |
String line; | |
boolean isWebSocket = false; | |
String webSocketKey = ""; | |
while (!(line = in.readLine()).equals("")) { | |
System.out.println(line); | |
String[] spLine = line.split(":"); | |
if (isWebSocket && spLine[0].equals("Sec-WebSocket-Key")) { | |
webSocketKey = spLine[1].trim(); | |
} | |
if (spLine[0].equals("Upgrade") && spLine[1].trim().equals("websocket")) { | |
isWebSocket = true; | |
} | |
} | |
if (isWebSocket) { | |
socketSet.add(socket); | |
WebSocketThread webSocketThread = new WebSocketThread(socket, webSocketKey); | |
webSocketThread.start(); | |
} else { | |
HttpResponseThread httpRequest = new HttpResponseThread(socket); | |
httpRequest.start(); | |
} | |
} | |
} | |
} | |
class HttpResponseThread extends Thread { | |
Socket socket; | |
public HttpResponseThread(Socket socket) { | |
this.socket = socket; | |
} | |
public void run() { | |
PrintStream client = null; | |
try { | |
Path indexPath = Paths.get("index.html"); | |
byte[] indexBytes = Files.readAllBytes(indexPath); | |
client = new PrintStream(socket.getOutputStream()); | |
client.println("HTTP/1.1 200 OK"); | |
client.println("Content_type:text/html"); | |
client.println(); | |
client.write(indexBytes); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} finally { | |
client.flush(); | |
client.close(); | |
} | |
} | |
} | |
class WebSocketThread extends Thread { | |
Socket socket; | |
String webSocketKey; | |
WebSocketThread(Socket socket, String webSocketKey) { | |
System.out.println("Start WebSocket Thread"); | |
this.socket = socket; | |
this.webSocketKey = webSocketKey; | |
} | |
public void run() { | |
OutputStreamWriter os = null; | |
try { | |
//Create Sec-WebSocket-Accept field. | |
webSocketKey += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; | |
MessageDigest md = MessageDigest.getInstance("SHA-1"); | |
byte[] cryptedKey = md.digest(webSocketKey.getBytes()); | |
byte[] encodedKey = Base64.getEncoder().encode(cryptedKey); | |
System.out.println(new String(encodedKey)); | |
//Response HTTP Upgrade Response Header. | |
StringBuffer header = new StringBuffer(); | |
header.append("HTTP/1.1 101 Switching Protocols\r\n"); | |
header.append("Upgrade: websocket\r\n"); | |
header.append("Connection: Upgrade\r\n"); | |
header.append("Sec-WebSocket-Accept: " + new String(encodedKey) + "\r\n"); | |
header.append("\r\n"); | |
os = new OutputStreamWriter(socket.getOutputStream()); | |
os.write(header.toString()); | |
System.out.println(header.toString()); | |
os.flush(); | |
//Parse received data. | |
byte[] b = new byte[1024]; | |
socket.getInputStream().read(b); | |
ByteBuffer buf = ByteBuffer.wrap(b); | |
byte firstByte = buf.get(); | |
int fin = (firstByte & 0x80) >>> 7; | |
int opcode = firstByte & 0x0F; | |
byte secondByte = buf.get(); | |
int mask = (secondByte & 0x80) >>> 7; | |
int payloadLength = secondByte & 0x7F; | |
int maskingKey = buf.getInt(); | |
int applicationData = buf.getInt(); | |
int unmaskedData = applicationData ^ maskingKey; | |
byte[] unmaskedByteData = new byte[4]; | |
unmaskedByteData[3] = (byte)(unmaskedData & 0xff); | |
unmaskedByteData[2] = (byte)(unmaskedData >> 8 & 0xff); | |
unmaskedByteData[1] = (byte)(unmaskedData >> 16 & 0xff); | |
unmaskedByteData[0] = (byte)(unmaskedData >> 24 & 0xff); | |
//Print received data. | |
System.out.println("fin:" + fin); | |
System.out.println("opcode:" + opcode); | |
System.out.println("mask:" + mask); | |
System.out.println("payloadLength:" + payloadLength); | |
System.out.println("maskingKey:" + maskingKey); | |
System.out.println("applicationData:" + new String(unmaskedByteData)); | |
//Send data. | |
ByteBuffer ob = ByteBuffer.allocate(6); | |
ob.put((byte)0x81); | |
ob.put((byte)0x4); | |
ob.put("test".getBytes()); | |
socket.getOutputStream().write(ob.array()); | |
socket.close(); | |
} catch (IOException | NoSuchAlgorithmException e) { | |
e.printStackTrace(); | |
} | |
} | |
} |
0 件のコメント:
コメントを投稿