这几天学习websocket终于把前后端都调通了,现在就记录一下.因为最后配置的apapche,印象比较深,就从apache配置开始.参考websocket;
apache支持配置
之前使用的xampp里的apache,是2.2版本的,不支持ws协议.所以昨天下午下午加今天早上把apapche配置都搞通了.先卸载了xampp,下载安装了2.4的apache 安装初步配置教程
先把 httpd.conf里的modules/mod_proxy_wstunnel.so
的注释去掉
再在 <VirtualHost *:80>
里配置ProxyPass /demo ws://localhost:4040/demo
前端js var socket = new WebSocket("ws://localhost/demo/actions");
这样就可以通过apache访问了
html+js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 80%;
background-color: #1f1f1f;
}
#wrapper {
width: 960px;
margin: auto;
text-align: left;
color: #d9d9d9;
}
p {
text-align: left;
}
.button {
display: inline;
color: #fff;
background-color: #f2791d;
padding: 8px;
margin: auto;
border-radius: 8px;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
box-shadow: none;
border: none;
}
.button:hover {
background-color: #ffb15e;
}
.button a, a:visited, a:hover, a:active {
color: #fff;
text-decoration: none;
}
#addDevice {
text-align: center;
width: 960px;
margin: auto;
margin-bottom: 10px;
}
#addDeviceForm {
text-align: left;
width: 400px;
margin: auto;
padding: 10px;
}
#addDeviceForm span {
display: block;
}
#content {
margin: auto;
width: 960px;
}
.device {
width: 180px;
height: 110px;
margin: 10px;
padding: 16px;
color: #fff;
vertical-align: top;
border-radius: 8px;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
display: inline-block;
}
.device.off {
background-color: #c8cccf;
}
.device span {
display: block;
}
.deviceName {
text-align: center;
font-weight: bold;
margin-bottom: 12px;
}
.removeDevice {
margin-top: 12px;
text-align: center;
}
.device.Appliance {
background-color: #5eb85e;
}
.device.Appliance a:hover {
color: #a1ed82;
}
.device.Electronics {
background-color: #0f90d1;
}
.device.Electronics a:hover {
color: #4badd1;
}
.device.Lights {
background-color: #c2a00c;
}
.device.Lights a:hover {
color: #fad232;
}
.device.Other {
background-color: #db524d;
}
.device.Other a:hover {
color: #ff907d;
}
.device a {
text-decoration: none;
}
.device a:visited, a:active, a:hover {
color: #fff;
}
.device a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div id="wrapper">
<h1>Java Websocket Home</h1>
<p>Welcome to the Java WebSocket Home. Click the Add a device button to start adding devices.</p>
<br />
<div id="addDevice">
<div class="button"> <a href="#" OnClick="showForm()">Add a device</a> </div>
<form id="addDeviceForm">
<h3>Add a new device</h3>
<span>Name: <input type="text" name="device_name" id="device_name"></span>
<span>Type:
<select id="device_type">
<option name="type" value="Appliance">Appliance</option>
<option name="type" value="Electronics">Electronics</option>
<option name="type" value="Lights">Lights</option>
<option name="type" value="Other">Other</option>
</select></span>
<span>Description:<br />
<textarea name="description" id="device_description" rows="2" cols="50"></textarea>
</span>
<input type="button" class="button" value="Add" onclick=formSubmit()>
<input type="reset" class="button" value="Cancel" onclick=hideForm()>
</form>
</div>
<br />
<h3>Currently connected devices:</h3>
<div id="content">
</div>
</div>
<script>
window.onload = init;
var socket = new WebSocket("ws://"+window.location.host+"/demo/actions");
socket.onmessage = onMessage;
function onMessage(e) {
var device = JSON.parse(e.data);
if(device.action === "add")
{
printDeviceElement(device);
}
if(device.action === "remove")
{
document.getElementById(device.id).remove();
device.parentNode.removeChild(device);
}
if(device.action === "toggle")
{
var node = document.getElementById(device.id);
var statusText = node.children[2];
if(device.status ==="On")
{
statusText.innerHTML = "Status: "+device.status+" (<a href\"#\" OnClick=toggleDevice("+device.id+")>Turn off</a>)";
}
else if(device.status === "Off")
{
statusText.innerHTML = "Status: "+device.status + " (<a href=\"#\" OnClick=toggleDevice("+device.id+")>Turn on</a>)";
deviceDiv.setAttribute("class", "device off");
}
}
}
function addDevice(name,type,description) {
var DeviceAction = {action:"add",name:name,type:type,description:description};
socket.send(JSON.stringify(DeviceAction));
}
function removeDevice(ele)
{
var id = ele;
var DeviceAction = {action:"remove",id:id};
socket.send(JSON.stringify(DeviceAction));
}
function toggleDevice(ele) {
var id = ele;
var DeviceAction = {action:"toggle",id:id};
socket.send(JSON.stringify(DeviceAction));
}
function printDeviceElement(device) {
var content = document.getElementById("content");
var deviceDiv = document.createElement("div");
deviceDiv.setAttribute("id", device.id);
deviceDiv.setAttribute("class","device "+device.type);
content.appendChild(deviceDiv);
var deviceName = document.createElement("span");
deviceName.setAttribute("class","deviceName");
deviceName.innerHTML = device.name;
deviceDiv.appendChild(deviceName);
var deviceType = document.createElement("span");
deviceType.innerHTML = "<b>Type:</b> "+device.type;
deviceDiv.appendChild(deviceType);
var deviceStatus = document.createElement("span");
if(device.status==="On")
{
deviceStatus.innerHTML = "<b>Status:</b>: "+device.status +" (<a href=\"#\" OnClick=toggleDevice("+device.id+")>Turn off</a>)";
}
else
{
deviceStatus.innerHTML = "<b>Status:</b> "+device.status+" (<a href=\"#\" OnClick=toggleDevice("+device.id+")>Turn on</a>";
}
deviceDiv.appendChild(deviceStatus);
var deviceDescription = document.createElement("span");
deviceDescription.innerHTML = "<b>Comments:</b> "+ device.description;
deviceDiv.appendChild(deviceDescription);
var removeDevice =document.createElement("span");
removeDevice.setAttribute("class","removeDeivce");
removeDevice.innerHTML = "<a href\"#\" OnClick=removeDevice("+device.id+")>Reomve device</a>";
deviceDiv.appendChild(removeDevice);
}
function showForm() {
document.getElementById("addDeviceForm").style.display = "";
}
function hideForm() {
document.getElementById("addDeviceForm").style.display = "none";
}
function formSubmit() {
var form = document.getElementById("addDeviceForm")
var name = form.elements["device_name"].value;
var type = form.elements["device_type"].value;
var description = form.elements["device_description"].value;
hideForm();
document.getElementById("addDeviceForm").reset();
addDevice(name,type,description);
}
function init() {
hideForm();
}
</script>
</body>
</html>
Java
com.xxx.model.Device
package com.xxx.model;
public class Device
{
private int id;
private String name;
private String status;
private String type;
private String description;
public Device()
{
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getType()
{
return type;
}
public void setType(String type)
{
this.type = type;
}
public String getDescription()
{
return description;
}
public void setDescription(String description)
{
this.description = description;
}
}
com.xxx.websocket.DeviceSessionHandler
package com.xxx.websocket;
import com.xxx.model.Device;
import org.springframework.stereotype.Component;
import javax.enterprise.context.ApplicationScoped;
import javax.json.JsonObject;
import javax.json.spi.JsonProvider;
import javax.websocket.Session;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
@ApplicationScoped
public class DeviceSessionHandler
{
private int deviceId = 0;
private final Set<Session> sessions = new HashSet<Session>();
private final Set<Device> devices = new HashSet<Device>();
public void addSession(Session session)
{
sessions.add(session);
for(Device device:devices)
{
JsonObject addMessage = createAddMessage(device);
sendToSession(session,addMessage);
}
}
public void removeSession(Session session)
{
sessions.remove(session);
}
public List<Device> getDevices()
{
return new ArrayList(devices);
}
public void addDevice(Device device)
{
device.setId(deviceId);
devices.add(device);
deviceId++;
JsonObject addMessage = createAddMessage(device);
sendToAllConnectedSessions(addMessage);
}
public void removeDevice(int id)
{
Device device = getDeviceById(id);
if(device != null)
{
devices.remove(device);
JsonProvider provider = JsonProvider.provider();
JsonObject removeMessage = provider.createObjectBuilder()
.add("action","remove")
.add("id",id)
.build();
sendToAllConnectedSessions(removeMessage);
}
}
public void toggleDevice(int id)
{
JsonProvider provider =JsonProvider.provider().provider();
Device device = getDeviceById(id);
if(device!=null)
{
if("On".equals(device.getStatus()))
device.setStatus("Off");
else
device.setStatus("On");
JsonObject updateMessage = provider.createObjectBuilder()
.add("action","toggle")
.add("id",device.getId())
.add("status",device.getStatus())
.build();
sendToAllConnectedSessions(updateMessage);
}
}
private Device getDeviceById(int id)
{
for(Device device:devices)
{
if(device.getId()==id)
return device;
}
return null;
}
private JsonObject createAddMessage(Device device)
{
JsonProvider provider = JsonProvider.provider();
JsonObject addMessage = provider.createObjectBuilder()
.add("action","add")
.add("id",device.getId())
.add("name",device.getName())
.add("type",device.getType())
.add("status",device.getStatus())
.add("description",device.getDescription())
.build();
return addMessage;
}
private void sendToAllConnectedSessions(JsonObject message)
{
for(Session session :sessions)
{
sendToSession(session,message);
}
}
private void sendToSession(Session session,JsonObject message)
{
try
{
session.getBasicRemote().sendText(message.toString());
} catch (IOException e)
{
sessions.remove(session);
Logger.getLogger(DeviceSessionHandler.class.getName()).log(Level.SEVERE,null,e);
}
}
}
com.xxx.websocket.DeviceWebSocketServer
package com.xxx.websocket;
import com.xxx.model.Device;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.StringReader;
import java.util.logging.Level;
import java.util.logging.Logger;
@ApplicationScoped
@ServerEndpoint("/actions")
public class DeviceWebSocketServer
{
@Inject
private DeviceSessionHandler sessionHandler;
@OnOpen
public void open(Session session)
{
sessionHandler.addSession(session);
}
@OnClose
public void close(Session session)
{
sessionHandler.removeSession(session);
}
@OnError
public void onError(Throwable error)
{
Logger.getLogger(DeviceWebSocketServer.class.getName()).log(Level.SEVERE,null,error);
}
@OnMessage
public void handleMessage(String message,Session session)
{
try(JsonReader reader = Json.createReader(new StringReader(message)))
{
JsonObject jsonMessage = reader.readObject();
if("add".equals(jsonMessage.getString("action")))
{
Device device = new Device();
device.setName(jsonMessage.getString("name"));
device.setDescription(jsonMessage.getString("description"));
device.setType(jsonMessage.getString("type"));
device.setStatus("Off");
sessionHandler.addDevice(device);
}
if("remove".equals(jsonMessage.getString("action")))
{
int id = jsonMessage.getInt("id");
sessionHandler.removeDevice(id);
}
if("toggle".equals(jsonMessage.getString("action")))
{
int id = jsonMessage.getInt("id");
sessionHandler.toggleDevice(id);
}
}
}
}
GlassFish
其实我想用tomcat来运行的,但是非常尴尬不知道怎么运行,按照oracle上的例子就只能用glassfish了.
tomcat是一个servlet容器,glassfish是一个javaee容器.所以glassfish也支持servlet,听说比较早的glassfish版本的sevrlet实现就是使用的tomcat.
安装 glassfish
先去下载 https://glassfish.java.net/download.html
下载下来
解压
在windows下点击
在控制台输入 start-domain
就可以启动了
intellij引入glassfish
在菜单栏里 run -> Edit Configurations
如果没找到xx items more(irrelevant)里找
第一次使用,需要配置glassfish所在的目录
Server Domain 选 domain1
然后在 Deployment选择发布的war包
这里说一句,Open browser里的地址是默认的使用8080端口,如果想改,访问glassfish的控制台,一般默认是localhost:4848 ,在这里稍等一会儿,它就会跳转到配置页面
修改端口后保存,应用就可以通过新端口来访问了
后记
这些都配好之后点击就可以运行了
运行成功了,可以做一些小操作