websocket chat app hands on on microsoft azure
TRANSCRIPT
-
Java on Azure
Azure WebSocket
Web Apps
Version: 1.0 Last updated: 2015/12/22
-
2
....................................................................................................................................................... 3 ................................................................................................................................................ 3 1 : WebSocket ...................................................................................................................... 4 2 : WebSocket ............................................. 8 Microsoft Azure .................................................................................... 8 WebSocket ................................................................................................. 11 WebSocket .................................................................................. 22 3 : WebSocket ............................................................... 35 WebSocket ................................................................................................. 35 WebSocket .................................................................................. 47 4 : ............................................................................................................................. 52
-
3
Microsoft Azure Web (PaaS) (IaaS) Microsoft Azure PaaS Web Apps WebSocket WebSocket JSON Java
WebSocket
WebSocket
WebSocket
6090
-
4
1 : WebSocket
WebSocket W3C IETF W3C API IETF WebSocket HTTP WebSocket Web (HTTP )Web Web Internet Explorer Microsoft Edge (Windows 10 )FirroxSafari Web http:// URL
Web (HTTP )
Web
-
5
HTML
Web Web Web
Ajax JavaScript
Web polling Web Reverse Ajax(Comet)Reverse Ajax (Comet) Web Streaming Long-Polling
Web
-
6
Reverse Ajax(Comet) Web Reverse Ajax Web HTTP HTTP (HTTP )Web Web API (HTTP ) Web (HTTP ) HTTP WebSocket W3C IETF Web
Web Web WebSocket WebSocket
WebSocket WebSocket
-
7
WebSocket
-
8
2 : WebSocket
WebSocket
Microsoft Azure
1,2 3, 4 Microsoft Azure 3, 4
1. DreamSpark http://yoshio3.com/2015/10/13/about-dreamspark-program/ 2. Microsoft Azure for DreamSpark http://yoshio3.com/2015/10/14/config-azure-for-dreamspark/
3. Java Web (JDK&NetBeans ) http://yoshio3.com/2015/10/15/prepare-java-dev-env/ 4. Microsoft Azure Web App NetBeans (Maven) FTP http://yoshio3.com/2015/10/16/config-ftp-4-azure-netbeans/
-
9
4. Microsoft Azure App ServiceWebSocketWebSocket Microsoft Azure App Service App Service
-
10
Web
-
11
WebSocket
WebSocket WebSocket HTML JavaScript HTML JavaScript WebSocket
index.html HTML
-
12
WebSocket WebSocket
-
13
HTML JavaScript Web jsjsWeb
(C):(F): >
-
14
-
15
(N):js(F)
-
16
Web js
jswebsocket-chat.jsJavaScript js
-
17
(C):(F):JavaScript >
-
18
(N):websocket-chat
-
19
jswebsocket-chat.jswebsocket-chat.js
JavaScript var websocket = null; var username = null; if (window.addEventListener) { //for W3C DOM window.addEventListener("load", init, false); } else if (window.attachEvent) { //for IE
-
20
window.attachEvent("onload", init); } else { window.onload = init; } /* */ function init() { showLoginButton(); } /* */ function connectServerEndpoint() { var wsUri = "ws://" + document.location.hostname + ":" + document.location.port + document.location.pathname + "chat-server"; // FireFox if ("WebSocket" in window) { websocket = new WebSocket(wsUri); } else if ("MozWebSocket" in window) { websocket = new MozWebSocket(wsUri); } websocket.onopen = function (evt) { showLogoutButton(); }; websocket.onmessage = function (evt) { ; }; websocket.onerror = function (evt) { console.log("WebSocket Error : " + evt); }; websocket.onclose = function (evt) { closeServerEndpoint(); }; }
-
21
/* */ function closeServerEndpoint() { websocket.close(4001, "Close connection from client"); showLoginButton(); } /* () */ function showLoginButton() { document.getElementById("login").style.display = "block"; document.getElementById("logout").style.display = "none"; } /* () */ function showLogoutButton() { document.getElementById("login").style.display = "none"; document.getElementById("logout").style.display = "block"; }
-
22
WebSocket
WebSocket
pom.xml slf4j pom.xml
4.0.0
-
23
com.yoshio3 Azure-Jetty9-WebSocket-JSF 1.0-SNAPSHOT war Azure-Jetty9-WebSocket-Chat ${project.build.directory}/endorsed UTF-8 javax javaee-web-api 7.0 provided javax.websocket javax.websocket-api 1.0 provided org.slf4j slf4j-api 1.7.10 org.slf4j slf4j-simple 1.7.10
-
24
org.apache.maven.wagon wagon-ftp 1.0-beta-3 org.mortbay.jetty jetty-maven-plugin 9.1.0.v20131115 org.codehaus.mojo wagon-maven-plugin 1.0-beta-3 upload-war install upload ${basedir}/target ${project.build.finalName}.war ftp://waws-prod-os1-001.ftp.azurewebsites.windows.net /site/wwwroot/webapps/ ftp-repository
-
25
org.apache.maven.plugins maven-compiler-plugin 3.1 1.7 1.7 ${endorsed.dir} org.apache.maven.plugins maven-war-plugin 2.3 false org.apache.maven.plugins maven-dependency-plugin 2.6 validate copy ${endorsed.dir} true
-
26
javax javaee-endorsed-api 7.0 jar
log4j Azure-Jetty9-WebSocket-Chat
-
27
log4j WebSocket Azure-Jetty9-WebSocket-ChatJava Java (C):Java(F):Java
-
28
(N):ChatServerEndpoint(F)
Java @ServerEndpoint(value = "/chat-server") public class ChatServerEndpoint { // private final static org.slf4j.Logger logger = LoggerFactory.getLogger(ChatServerEndpoint.class); // Jetty // private static final Set< Session> sessions = Collections.synchronizedSet(new HashSet()); @OnOpen public void onOpen(Session session) throws IOException { logger.info("onOpen: " + session.getId()); sessions.add(session);
-
29
logger.info("onOpen Number of sessions: " + sessions.size()); } @OnClose public void onClose(Session session) throws IOException { logger.info("onClose: " + session.getId()); sessions.remove(session); logger.info("onClose Number of sessions: " + sessions.size()); } @OnError public void onError(Throwable p) { logger.error("WebSocket onError : ", p); } }
Azure-Jetty9-WebSocket-Chat
Microsoft Azure FTP BUILD SUCCESS
-
30
Microsoft Azure Web
-
31
()Web
Web URL
-
32
URL http://*****-*****.azurewebsites.net/Azure-Jetty9-WebSocket-Chat
$ ftp waws-prod-os1-001.ftp.azurewebsites.windows.net Trying 138.91.24.26... Connected to waws-prod-os1-001.drip.azurewebsites.windows.net. 220 Microsoft FTP Service
-
33
Name (waws-prod-os1-001.ftp.azurewebsites.windows.net:yoterada): yosshi2007-jettyyosshi2007-dep 331 Password required Password: 230 User logged in. Remote system type is Windows_NT. ftp> ls 229 Entering Extended Passive Mode (|||10083|) 125 Data connection already open; Transfer starting. 10-22-15 11:54AM LogFiles 10-22-15 11:03AM site 226 Transfer complete. ftp> cd LogFiles 250 CWD command successful. ftp> ls 229 Entering Extended Passive Mode (|||10085|) 125 Data connection already open; Transfer starting. 10-22-15 11:40AM DetailedErrors 10-22-15 11:55AM 4655 eventlog.xml 10-22-15 11:04AM http 10-22-15 11:55AM 0 jetty_2015_10_22.stderrout.log 10-22-15 11:03AM kudu 10-22-15 11:16AM SiteExtensions 10-22-15 11:40AM W3SVC647188608 226 Transfer complete. ftp>
-
34
ftp> ls 229 Entering Extended Passive Mode (|||10094|) 125 Data connection already open; Transfer starting. 10-22-15 11:40AM DetailedErrors 10-22-15 11:55AM 4655 eventlog.xml 10-22-15 11:04AM http 10-22-15 11:57AM 0 jetty_2015_10_22.stderrout.log 10-22-15 11:55AM 1485 jetty_2015_10_22.stderrout.log.115749862 10-22-15 11:03AM kudu 10-22-15 11:16AM SiteExtensions 10-22-15 11:40AM W3SVC647188608 226 Transfer complete. ftp> get jetty_2015_10_22.stderrout.log.115749862 local: jetty_2015_10_22.stderrout.log.115749862 remote: jetty_2015_10_22.stderrout.log.115749862 229 Entering Extended Passive Mode (|||10093|) 125 Data connection already open; Transfer starting. 100% |****************************************************************************************| 1485 93.97 KiB/s 00:00 ETA 226 Transfer complete. 1485 bytes received in 00:00 (62.74 KiB/s) ftp> quit 221 Goodbye.
2015-10-22 11:55:23.848:INFO:oejs.Server:main: jetty-9.1.0.v20131115 2015-10-22 11:55:23.895:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:/D:/home/site/wwwroot/webapps/] at interval 1 2015-10-22 11:55:25.192:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@1fcfece{/Azure-Jetty9-WebSocket-JSF,file:/D:/local/Temp/jetty-127.0.0.1-17537-Azure-Jetty9-WebSocket-JSF-1.0-SNAPSHOT.war-_Azure-Jetty9-WebSocket-JSF-1.0-SNAPSHOT-any-2705390846338938535.dir/webapp/,AVAILABLE}{D:homesitewwwrootwebappsAzure-Jetty9-WebSocket-JSF-1.0-SNAPSHOT.war}
-
35
2015-10-22 11:55:25.301:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@4718df{/,file:/D:/home/site/wwwroot/webapps/ROOT/,AVAILABLE}{D:homesitewwwrootwebappsROOT} 2015-10-22 11:55:25.411:INFO:oejs.ServerConnector:main: Started ServerConnector@1dc3715{HTTP/1.1}{127.0.0.1:17537} [qtp26111414-61] INFO com.yoshio3.ChatServerEndpoint - onOpen: websocket-1 [qtp26111414-58] INFO com.yoshio3.ChatServerEndpoint - onClose: websocket-1 [qtp26111414-62] INFO com.yoshio3.ChatServerEndpoint - onOpen: websocket-2 [qtp26111414-61] INFO com.yoshio3.ChatServerEndpoint - onClose: websocket-2 [qtp26111414-58] INFO com.yoshio3.ChatServerEndpoint - onOpen: websocket-3 [qtp26111414-62] INFO com.yoshio3.ChatServerEndpoint - onClose: websocket-3 [qtp26111414-61] INFO com.yoshio3.ChatServerEndpoint - onOpen: websocket-4 [qtp26111414-58] INFO com.yoshio3.ChatServerEndpoint - onClose: websocket-4
FTP
3 : WebSocket
WebSocket WebSocket
WebSocket
Connect
-
36
WebSocket
-
37
index.html HTML WebSocket WebSocket
-
38
websocket-chat.js JavaScript WebSocket
-
39
JavaScript websocket-chat.js var websocket = null; var username = null; if (window.addEventListener) { //for W3C DOM window.addEventListener("load", init, false); } else if (window.attachEvent) { //for IE window.attachEvent("onload", init); } else { window.onload = init; } /* */ function init() { // chat showLoginButton(); } /* */ function connectServerEndpoint() { var wsUri = "ws://" + document.location.hostname + ":"
-
40
+ document.location.port + document.location.pathname + "chat-server"; // FireFox if ("WebSocket" in window) { websocket = new WebSocket(wsUri); } else if ("MozWebSocket" in window) { websocket = new MozWebSocket(wsUri); } //Chat ) showChatMessage(); websocket.onopen = function (evt) { username = document.getElementById("name").value; sendMessage(username + " "); }; websocket.onmessage = function (evt) { writeToScreen(evt); }; websocket.onerror = function (evt) { console.log("WebSocket Error : " + evt); }; websocket.onclose = function (evt) { closeServerEndpoint(); }; } /* */ function closeServerEndpoint() { sendMessage(username + " "); websocket.close(4001, "Close connection from client"); showLoginButton(); } /* */ function sendMessage(message) { websocket.send(message); } /* */
-
41
function submitMessage() { msg = document.getElementById("inputMessage").value; sendMessage(username + " : " + msg); } /* */ function writeToScreen(evt) { var element = document.createElement('div'); element.className = "message"; element.textContent = evt.data; element.style.backgroundColor = "white"; // var objBody = document.getElementById("insertpos"); objBody.insertBefore(element, objBody.firstChild); // bodydiv } /* () */ function showLoginButton() { document.getElementById("login").style.display = "block"; document.getElementById("chat").style.display = "none"; } /* () */ function showChatMessage() { document.getElementById("login").style.display = "none"; document.getElementById("chat").style.display = "block"; }
JavaScript WebSocket var websocket = null; var username = null; websocket.onopen = function (evt) { username = document.getElementById("name").value; sendMessage(username + " "); }; /* */
-
42
function sendMessage(message) { websocket.send(message); }
document.getElementById("name").value sendMessage()sendMessage() WebSocket username //Chat ) showChatMessage(); /* () */ function showChatMessage() { document.getElementById("login").style.display = "none"; document.getElementById("chat").style.display = "block"; }
WebSocket showChatMessage()
(none)(block) /* */ function submitMessage() { msg = document.getElementById("inputMessage").value; sendMessage(username + " : " + msg); }
submitMessage()username : WebSocket /* */ function closeServerEndpoint() { sendMessage(username + " "); websocket.close(4001, "Close connection from client");
-
43
showLoginButton(); }
WebSocket closeServerEndpoint()username WebSocket websocket.onmessage = function (evt) { writeToScreen(evt); }; /* */ function writeToScreen(evt) { var element = document.createElement('div'); element.className = "message"; element.textContent = evt.data; element.style.backgroundColor = "white"; // var objBody = document.getElementById("insertpos"); objBody.insertBefore(element, objBody.firstChild); // bodydiv }
WebSocket JavaScript websocket.onmessage()onmessage()writeToScreen() writeToScreen()(objBody.firstChild)(insertBefore)writeToScreen() HTML :
CSS
-
44
NetBeans Web
(N):css(F)
css
-
45
(C):HTML5(F):Cascading Style Sheet >
-
46
(N):ws-chat(F)
ws-chat.css /* 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. */ /* Created on : 2015/11/10, 16:11:05 Author : Yoshio Terada */ .title{ position:relative; margin:0 auto; width:480px; overflow:hidden;
-
47
} .login{ position:relative; margin:0 auto; width:480px; overflow:hidden; } .chat{ position:relative; margin:0 auto; width:480px; overflow:hidden; } .chat .messages{ width:100%; height:480px; overflow:hidden; } .chat .messages:hover{ overflow-y:scroll; } .chat .messages > div{ padding:15px; border-bottom:1px dashed #999; }
WebSocket
WebSocket
WebSocket onMessage()onMessage() /* * Copyright 2015 Yoshio Terada *
-
48
* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.yoshio3; import java.io.IOException; import java.util.Collections; import java.util.HashSet; import java.util.Set; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; /** * * @author Yoshio Terada */ @ServerEndpoint(value = "/chat-server") public class ChatServerEndpoint { // Jetty private static final Set< Session> sessions = Collections.synchronizedSet(new HashSet()); @OnOpen
-
49
public void onOpen(Session session) throws IOException { sessions.add(session); } @OnMessage public void onMessage(String message, Session session) throws IOException { //Jetty 9.1.0.v20131115 Java SE 8 //Java SE 7 (Lambda ) //Jetty //Set sessions = session.getOpenSessions(); // null NullPointerException // //https://bugs.eclipse.org/bugs/show_bug.cgi?id=422192 for (Session sess : sessions) { if (sess.isOpen()) { sess.getBasicRemote().sendText(message); } } } @OnClose public void onClose(Session session) throws IOException { sessions.remove(session); } @OnError public void onError(Throwable p) { System.out.println("onError " + p.getMessage()); } }
Set sessions sess.getBasicRemote().sendText(message)
-
50
Azure-Jetty9-WebSocket-Chat
Microsoft Azure FTP BUILD SUCCESS
Web URL http://*****-*****.azurewebsites.net/Azure-Jetty9-WebSocket-Chat URL WebSocket
-
51
-
52
WebSocket WebSocket
4 :
WebSocket RFC 6455 WebSocket Protocol https://tools.ietf.org/html/rfc6455 W3C The WebSocket API http://www.w3.org/TR/2011/WD-websockets-20110929/ JSR 356: Java API for WebSocket https://jcp.org/en/jsr/detail?id=356 Java EE 7 WebSocket SlideShare Java EE 7 Detail http://www.slideshare.net/OracleMiddleJP/java-ee-7-detail/142 SlideShare Java EE 7 http://yoshio3.com/2013/10/23/java-ee-7-hol-on-jjug-ccc/ Twitter http://yoshio3.com/2012/11/12/websocket-twitter-timeline-sample/ WebSocket Mailer http://yoshio3.com/2013/12/20/java-ee-7-websocket-anti-pattern/