websocket chat app hands on on microsoft azure

52
Java on Azure ハンズオン Azure WebSocket を体験しよう! Web Apps Version: 1.0 Last updated: 2015/12/22

Upload: yoshio-terada

Post on 16-Apr-2017

12.125 views

Category:

Technology


2 download

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/