PRO HTML5 PROGRAMMING POWERFUL APIS FOR RICHER INTERNET APPLICATION DEVELOPMENT
CHAP 1. OVERVIEW OF HTML5
HTML was first published as an Internet draft in Version 2.0, 3.2, 4.0 occurred in the same year, and finally 4.01 in HTML5 specification was created by Web Hypertext Application Working Group (WHATWG) in W3C became involved with HTML again in 2006 and published first working draft in 2008, and XHTML 2 stopped in HISTORY OF HTML5
HTML5 spec. is a working draft today (not final). 2012: candidate recommendation. (HTML5 will be complete ) 2022: proposed recommendation. IE6 does not support many of new features. Microsoft promises to design that browser with increased HTML5 support. MYTH OF 2022
Web Hypertext Application Technology Working Group (WHATWG) Founded in 2004 Vendors: Apple, Mozilla, Google, Opera World Wide Web Consortium (W3C) Internet Engineering Task Force (IETF) HTML5 defines a new WebSocket API that relies on a new WebSocket protocol. WHO IS DEVELOPING HTML5
Compatibility Utility - Separation of Presentation and Content Most of presentational features of earlier versions of HTML are no longer supported (but will still work!). Shortages of older versions of HTML Poor accessibility Unnecessary complexity (Harder to read code) Large document size – slower loading pages Interoperability - Simplify wherever possible Native browser ability instead of complex JavaScript code A new, simplified character set declaration Powerful yet simple HTML5 APIs Universal access: Accessibility Media independence Support for all world languages: Ex: supports Ruby annotation CHARACTERISTICS OF HTML5
Present problem of plugin Cannot always be installed Can be disabled or blocked (Ex: iPad does not ship with a Flash plugin) Often blocked in controlled corporate environments Users disable because of unwelcome advertising A separate attack vector Difficult to integrate with the rest of HTML document A PLUGIN – FREE PARADIGM
Canvas (2D or 3D) Channel messaging Cross-document messaging Geolocation MathML Microdata Server-Sent Event Scalable Vector Graphics (SVG) WebSocket API and protocol Web origin concept Web Storage Web SQL database Web Workers XMLHTTPRequest Level 2 HTML5 FEATURES
DOCTYPE Character set NEW DOCTYE AND CHARACTER SET
Content TypeDescription EmbeddedImports other resources into the document, EX: audio, video, canvas, and iframe FlowElements used in the body of documents and applications, EX: form, h1, and small HeadingSection headers, EX: h1, h2, and hgroup InteractiveContent that users interact with, EX: audio or video controls, button, and textarea MetadataCommonly found in the head section— Set up the presentation or behavior of the rest of the document, EX: script, style, and title PhrasingText and text markup elements, EX: mark, kbd, sub, and sup SectioningElements that define sections in the document, EX: article, aside, and title NEW AND DEPRECATED ELEMENTS Deprecated Elements: Elements perform inline styling in favor of using CSS, Ex: big, center, font
The sectioning content type is useful for search engine. New sectioning HTML5 elements SEMANTIC MARKUP Sectioning Element Description headerHeader content (for a page or a section of the page) footerFooter content (for a page or a section of the page) sectionA section in a web page articleIndependent article content asideRelated content or pull quotes navNavigational aids
Define the relationship between a document and an external resource Placed at Attributes HTML5 TAG - AttributeValueDescription hrefURLSpecifies the location of the linked document relAlternate/author/help/icon/licenc e/next/pingback/prefetch/prev/se arch/sidebar/stylesheet/tag Specifies the relationship between the current document and the linked document Example:
webkit and moz mean they are not W3C standard webkit Supported by Safari and Chrome -webkit-box-shadow: 2px 2px 20px #888; (Shadow effect) -webkit-transform: rotate(-45deg); (Rotate effect) -webkit-transform: scale(0.5); (Change size) -webkit-border-radius: 10px; moz Supported by Mozilla -moz-box-shadow: 2px 2px 20px #888; (Shadow effect) -moz-transform: rotate(-45deg); (Rotate effect) CSS – WEBKIT/MOZ Excerise: Listing 1-1, 1-2
SIMPLIFYING SECTION – SELECTORS API FunctionExample getElementById() getElementById("foo"); getElementsByName() getElementsByName("foo"); getElementsByTagName() getElementsByTagName("input"); FunctionExampleResult querySelector()querySelector("input.error")Return the first input field with a style class of “error” querySelectorAll()querySelectorAll("#results td")Return any table cells inside the element with id results HTML4 HTML5 Excerise: Listing 1-3 HTML5
JSON A relatively new and increasing popular way to represent data Data is represented as objects In older browsers, a JavaScript library ( is necessary. Parsing and serializing are not always fast enough Newer browsers have a native implementation of JSON DOM Level 3 Most browsers support standard APIs for events and elements, Internet Explorer differs. IE9 will support DOM level 2 and 3 features. WINDOWS.JSON AND DOM LEVEL 3
CHAP 3. AUDIO/VIDEO API
An audio or video file is really just a container file, similar to a ZIP archive file that contains a number of files. Some of the popular video container formats include the following: Audio Video Interleave (.avi) Flash Video (.flv) MPEG 4 (.mp4) Matroska (.mkv) Ogg (.ogv) VIDEO CONTAINER
Audio and video coders/decoders (codecs) are algorithms used to encode and decode a particular audio or video stream so that they can be played back. Some example audio codecs are the following: AAC MPEG-3 Ogg Vorbis Example video codecs are the following: H.264 VP8 Ogg Theora AUDIO AND VIDEO CODECS
Streaming audio and video. That is, there is currently no standard for bitrate switching in HTML5 video Media is restricted by HTTP cross-origin resource sharing. Full-screen video is not scriptable Because it could be considered a security violation to let a scriptable element take over the full screen. Accessibility for audio and video elements is not fully specified yet. Work is underway on a specification called WebSRT for subtitle support based on the popular SRT format. RESTRICTIONS
Browser support for HTML5 Video Checking for Browser Support JavaScript var hasVideo = !!(document.createElement('video').canPlayType); HTML Fallback content Your browser does not support HTML5 video. BROWSER SUPPORT BrowserDetails ChromeVersion 3.0 and greater FirefoxVersion 3.5 and greater Internet Explorer Not supported OperaVersion 10.5 and greater SafariVersion 3.2 and greater
Audio An audio clip from Johann Sebastian Bach. Video HTML USAGE
Common control functions TAKING CONTROL FunctionsBehavior load()Loads the media file and prepares it for playback. Normally does not need to be called unless the element itself is dynamically created. Useful for loading in advance of actual playback. play()Loads (if necessary) and plays the media file. Plays from the beginning unless the media is already paused at another position. pause()Pauses playback if currently active. canPlayType(type)Tests to see whether the video element can play a hypothetical file of the given MIME type.
Play function toggleSound() { var music = document.getElementById("clickSound"); var toggle = document.getElementById("toggle"); if (music.paused) { // 檢查是否已暫停 music.play(); toggle.innerHTML = "Pause"; } else { music.pause(); toggle.innerHTML ="Play"; } WORKING WITH AUDIO
CHAP 2. CANVAS API
Dynamically generate and render graphics, charts, images and animations SVG (Scalable Vector Graphics) vs. Canvas Bitmap canvas Images drawn on a canvas are final and not be resized Objects drawn on a canvas are not part of the page’s DOM or any namespace SVG images can be scaled seamlessly at different resolutions and allow hit detection HTML5 Canvas API It performs well because it does not have to store objects for every primitive it draws Relatively easy to implement the Canvas API WHAT IS CANVAS
Element: Coordinates: CANVAS BrowserDetails ChromeSupported in version 1.0 and greater FirefoxSupported in version 1.5 and greater Internet Explorer Not supported OperaSupported in version 9.0 and greater SafariSupported in version 1.3 and greater
CHECKING BROWSER SUPPORT try { document.createElement("canvas").getContext("2d"); document.getElementById("support").innerHTML = "HTML5 Canvas is supported in your browser."; } catch (e) { document.getElementById("support").innerHTML = "HTML5 Canvas is not supported in your browser."; }
A basic canvas with solid border Get the canvas element and its context var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); Draw line Prepare graph context.beginPath(); context.moveTo(70, 140); context.lineTo(140, 70); Stroke graph onto the canvas context.stroke(); CANVAS, DRAW LINE Excerise
TRANSFORMATION (TRANSLATE, SCALE, ROTATE)
Get the canvas element and its context Save the current drawing state context.save(); Move to new coordinate, ex: (50, 100) context.translate(50, 100); Draw line Restore the old drawing state context.restore(); TRANSLATION Excerise
PATH context.beginPath(); context.moveTo(-25, -50); context.lineTo(-10, -80); context.lineTo(-20, -80); context.lineTo(-5, -110; context.lineTo(-15, -110); context.lineTo(0, -140); context.lineTo(15, -110); context.lineTo(5, -110); context.lineTo(20, -80); context.lineTo(10, -80); context.lineTo(25, -50); ontext.closePath();
Line width context.lineWidth = 4; Corner style at path joins (round: 圓角, bevel: 斜角, miter) context.lineJoin = 'round'; Line style at endpoints (round, square, butt: 預設值 ) Context.lineCap = ‘square'; Stroke style Change color context.strokeStyle = '#663300'; Background pattern Fill Style Change color context.fillStyle = '#339900'; Background pattern Fill the region inside all the closed paths context.fill(); Fill rectangular content context.fillRect(x, y, w, h); //ex: context.fillRect(-5, -50, 10, 50); STROKE STYLE
Starting Point: current location context.quadraticCurveTo(ControlPointX, ControlPointY, EndPointX, EndPointY); Example: context.save(); context.translate(-10, 350); cucontext.moveTo(0, 0); context.quadraticCurveTo(170, -50, 260, -190); context.quadraticCurveTo(310, -250, 410, -250); context.lineWidth = 20; context.strokeStyle = '#663300'; ontext.stroke(); context.restore(); QUADRATIC CURVE
Load image var img = new Image(); img.src = “bark.jpg”; Confirm the image is loaded img.onload = function(){ //Draw image onto canvas } Draw image onto canvas context.drawImage(image, dx, dy) context.drawImage(image, dx, dy, dw, dh) context.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) Example var bark = new Image(); bark.src = "bark.jpg"; bark.onload = function(){ context.drawImage(bark, -5, -50, 10, 50); context.stroke(); context.restore(); } IMAGE
Linear Gradient ( 漸層 ) Usage context.createLinearGradient(x0, y0, x1, y1) x0, y0 - Line start x1, y1 - Line end gradient.addColorStop(offset, color) offset - From 0.0 to 1.0 color - Use rgba() or HEX Example var trunkGradient = context.createLinearGradient(-5, -50, 5, -50); trunkGradient.addColorStop(0, '#663300'); trunkGradient.addColorStop(0.4, '#996600'); trunkGradient.addColorStop(1, '#552200'); context.fillStyle = trunkGradient; context.fillRect(-5, -50, 10, 50); Radical Gradient Usage Context.createRadicalGradient(x0, y0, r0, x1, y1, r1) x0, y0, r0 – First circle center at (x0, y0) with radius r0 x1, y1, r1 – Second circle center at (x1, y1) with radius r1 GRADIENT
Usage context.createPattern(image, repeat) repeat - repeat, repeat-x, repeat-y, no-repeat Example var gravel = new Image(); gravel.src = "gravel.jpg"; context.save(); context.translate(-10, 390); gravel.onload = function(){ context.beginPath(); context.moveTo(0, 0); context.quadraticCurveTo(170, -50, 260, -190); context.quadraticCurveTo(310, -250, 410, -250); context.lineWidth = 20; context.strokeStyle = context.createPattern(gravel, 'repeat'); context.stroke(); context.restore(); } BACKGROUND PATTERN
Usage context.scale(rx, ry); rx – width scale ratio ry – height scale ratio Example var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); context.save(); context.translate(260, 500); context.scale(2, 2); drawTree(context); context.restore(); SCALE
Usage context.rotate(angle) angel can be express with Math.PI/180 * degree Example var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); context.save(); context.translate(260, 500); context.rotate(Math.PI/180 * 40); drawTree(context); context.restore(); ROTATE
Context.transform(rx, sy, sx, ry, dx, dy) rx – width scale ratio ry – height scale ratio sy – vertical shear sx – horizontal shear Example var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); context.save(); context.translate(130, 250); context.transform(1, 0, -0.5, 1, 0, 0); context.scale(1, 0.6); context.fillStyle = 'rgb(0, 0, 0, 0.2)'; context.fillRect(-5, -50, 10, 50); createCanopyPath(context); context.fill(); context.restore(); TRANSFORM
Usage context.fillText(text, x, y, maxwidth) context.strokeText(text, x, y, maxwidth) Property context.font = Font String context.textAlign = start, end, left, right, center context.textBaseLine = top, middle, bottom, … Example context.save(); context.font = '60px 標楷體 '; context.fillStyle = '#996600'; context.textAlign = 'center'; context.fillText(' 快樂圖畫 ', 200, 60, 400); context.restore(); CANVAS TEXT
Usage shadowColor – Any CSS Color shadowOffsetX – Pixel Count shadowOffsetY – Pixel Count Shadowblur – Gaussian blur Example context.shadowColor = 'rgba(0, 0, 0, 0.2)'; context.shadowOffsetX = 15; context.shadowOffsetY = -10; context.shadowBlur = 2; context.font = '60px 標楷體 '; context.fillStyle = '#996600'; context.textAlign = 'center'; context.fillText(' 快樂圖畫 ', 200, 60, 400); SHADOWS
CHAP 4. GEOLOCATION API
You can request users to share their location and, if they agree, you can provide them with instructions on how to get to a nearby store to pick up a new pair of shoes at a discounted rate. You request a position and, if the user agrees, the browser returns location information. The position is provided to the browser by the underlying device (for example, a laptop or a mobile phone) on which the HTML5 Geolocation–enabled browser is running. IP Address Global Positioning System (GPS) Wi-Fi with MAC addresses from RFID, Wi-Fi, and Bluetooth GSM or CDMA cell phone IDs ABOUT LOCATION INFORMATION
ProsCons GPS Very accurate Take a long time, can drain a user’s device’s batteries Does not work well indoors May require additional hardware Wi-Fi Accurate Works indoors Fix quickly & cheaply Not good in rural areas with few wireless access points Cell Phone Fairly accurate Works indoors Fix quickly & cheaply Requires a device with access to a cell phone or cell modem Not good in rural areas with fewer cell phone towers User-Defined May have more accurate location data Allows services for alternate locations User entry might be faster than detection Can also be very inaccurate, especially if the location changes THE PROS AND CONS OF GEOLOCATION DATA
The browser intercepts and requests user permission at step 2. ARACHITECTURE & PRIVACY
Browser support for HTML5 Geolocation BROWSER SUPPORT BrowserDetails ChromeSupported in Google Chrome version 2 with Gears FirefoxSupported in version 3.5 and greater Internet ExplorerSupported via the Gears plugin OperaPlanned support version 10, experimental support in nightly builds SafariSupported in version 4 for the iPhone
if(navigator.geolocation) { document.getElementById("support").innerHTML = "HTML5 Geolocation supported."; } else { document.getElementById("support").innerHTML = "HTML5 Geolocation is not supported in your browser."; } CHECKING FOR BROWSER SUPPORT
Theres are two type of position requests One-shot position request Repeated position updates POSITIONS REQUESTS
Usage void getCurrentPosition(in PositionCallback successCallback, in optional PositionErrorCallback errorCallback, in optional PositionOptions options); Example navigator.geolocation.getCurrentPosition(updateLocation, handleLocationError, {timeout:10000}); updateLocation is a PositionCallback function will implement later handleLocationError is a PositionErrorCallback function will implement later ONE-SHOT POSITION REQUESTS
function updateLocation(position) { var latitude = position.coords.latitude; var longitude = position.coords.longitude; var accuracy = position.coords.accuracy; document.getElementById("latitude").innerHTML = latitude; document.getElementById("longitude").innerHTML = longitude; document.getElementById(“accuracy”).innerHTML = “This location is accurate within “ +accuracy + “ meters.” } IMPLEMENT POSITION CALLBACK
function handleLocationError(error) { switch(error.code) { case 0: updateStatus(“Retrieving location error: " + error.message); break; case 1: updateStatus("The user prevented retrieving location."); break; case 2: updateStatus(“Unable to determine your location: " + error.message); break; case 3: updateStatus(“Retrieving timed."); break; } IMPLEMENT POSITION ERROR CALLBACK
Usage long watchPosition(in PositionCallback successCallback, in optional PositionErrorCallback errorCallback, in optional PositionOptions options); Example navigator.geolocation.watchPosition(updateLocation, handleLocationError); updateLocation is a PositionCallback function same as getCurrentPosition implemented above. handleLocationError is a PositionErrorCallback function same as getCurrentPosition implemented above. REPEAT POSITION UPDATES
Usage navigator.geolocation.clearWatch(watchId); Example var watchId = navigator.geolocation.watchPosition(updateLocation, handleLocationError); navigator.geolocation.clearWatch(watchId); CANCEL POSITION UPDATES
Require Google Map JavaScript API Put Div for Google Map SHOW ME ON A GOOGLE MAP
Google Map Example var map; function initialize() { map = new google.maps.Map(document.getElementById('map_canvas'), {zoom: 15, mapTypeId: google.maps.MapTypeId.ROADMAP}); navigator.geolocation.getCurrentPosition(function(position) { var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); var infowindow = new google.maps.InfoWindow({ map: map, position: pos, content: 'Location found using HTML5.‘ }); map.setCenter(pos); }, function(error) { alert('Cannot get Location data: ' + error.code); }); } window.addEventListener("load", initialize, true); SHOW ME ON A GOOGLE MAP (CONT.)
CHAP 5. COMMUNICATION API
Communications between frames, tabs, and windows in a running browser was entirely restricted due to security concerns. If browsers granted the ability to programmatically access the content loaded into other frames and tabs, sites would be able to steal whatever information they could get from another site's content using scripting CROSS DOCUMENT SECURITY ISSUE
However, there are some legitimate cases for content from different sites to be able to communicate inside the browser. The classic example is the "mashup", a combination of different applications such as mapping, chat, and news from different sites, all combined together to form a new meta- application. To meet this need, the browser vendors and standards bodies agreed to introduce a new feature: Cross Document Messaging. CROSS DOCUMENT MESSAGING
CROSS DOCUMENT MESSAGING (CONT.)
HTML5 clarifies and refines domain security by introducing the concept of an origin. An origin is a subset of an address used for modeling trust relationships on the Web. Origins are made up of a scheme, a host, and a port. Cross-origin communication identifies the sender by origin. This allows the receiver to ignore messages from origins it does not trust or does not expect to receive messages from. UNDERSTANDING ORIGIN SECURITY
Browser support for HTML5 Cross Document Messaging Checking for Browser Support if (typeof window.postMessage === “undefined”) { // postMessage not supported in this browser } BROWSER SUPPORT BrowserDetails ChromeSupported in version 2.0 and greater FirefoxSupported in version 3.0 and greater Internet ExplorerSupported in version 8.0 and greater OperaSupported in version 9.6 and greater SafariSupported in version 4.0 and greater
Usage window.postMessage(“Hello, world”, “portal.example.com”); Example document.getElementsByTagName(“iframe”)[0].contentWindow.post Message(“Hello, world”, “chat.example.net”); SENDING MESSAGES
Example: function messageHandler(e) { if(checkWhiteList(e.origin)) { processMessage(e.data); } else { // ignore messages from unrecognized origins } } window.addEventListener(“message”, messageHandler, true); checkWhiteList is a function to check e.origin whether is legal. LISTEN FOR MESSAGE EVENTS
XMLHttpRequest is the API that made Ajax possible. XMLHttpRequest Level 2—the new version of XMLHttpRequest—has been significantly enhanced. Cross-origin XMLHttpRequests Progress events XML HTTPREQUEST LEVEL 2
CROSS-ORIGIN XMLHTTPREQUEST
XMLHttpRequest Level 2 allows for cross-origin XMLHttpRequests using Cross Origin Resource Sharing (CORS) CORS uses the origin concept discussed in the earlier Cross Document Messaging section. Cross-origin HTTP requests have an Origin header. This header provides the server with the request’s origin. This means that successful communication may require a CORS-capable server. CROSS-ORIGIN XMLHTTPREQUEST (CONT.)
Access-Control-Allow-Origin: Access-Control-Allow-Credentials: true CORS HEADER IN HTTP PROTOCOL
In the previous version of XMLHttpRequest, there was only a single readystatechange event. The readyState change event lacked a way to communicate upload progress. Implementing an upload progress bar was not a trivial task and involved server-side participation. XMLHttpRequest Level 2 introduces progress events with meaningful names. PROGRESS EVENT Progress Event Name loadstart progress abort error load loadend
Browser support for HTML5 XMLHttpRequest BROWSER SUPPORT BrowserDetails ChromeSupported in version 2.0 and greater FirefoxSupported in version 3.5 and greater Internet ExplorerNot supported OperaNot supported SafariSupported in version 4.0 and greater
var xhr = new XMLHttpRequest(); if (typeof xhr.withCredentials === undefined) { // Your browser does not support cross-origin XMLHttpRequest"; } else { // Your browser does support cross-origin } CHECKING FOR BROWSER SUPPORT
Example var crossOriginRequest = new XMLHttpRequest(); crossOriginRequest.open("GET", " true); Make sure, you listen for errors. There are many reasons why this request might not succeed. For example, network failure, access denied, and lack of CORS support on the target server MAKING CROSS-ORIGIN REQUESTS
Example crossOriginRequest.onprogress = function(e) { var total = e.total; var loaded = e.loaded; if (e.lengthComputable) { // do something with the progress information } } USING PROGRESS EVENTS
Example: var xhr = new XMLHttpRequest(); var targetLocation = “ Document.getElementById(“sendButton”).addEventListener(“click”, function() { xhr.upload.onprogress = function(e) { Var ratio = e.loaded / e.total; setProgress(ratio + “% uploaded”); } xhr.onprogress = function(e) { Var ratio = e.loaded / e.total; setProgress(ratio + “% downloaded”); } xhr.onload = function(e) { setProgress(“finished”); } xhr.onerror = function(e) { setProgress(“error”); } xhr.open(“POST”, targetLocation, true); var filesToBeUploaded = document.getElementById("fileUpload"); var file = filesToBeUploaded.files[0]; // 取得欲上傳的檔案 xhr.send(file); }, true); USING PROGRESS EVENTS
CHAP 5. WEBSOCKET API
In many cases (stock prices, news reports …) which you want get real-time information, you can constantly refresh that page. But that’s obviously not a great solution. With polling, the browser sends HTTP requests at regular intervals and immediately receives a response. Making unnecessary requests inevitable and as a result, many connections are opened and closed needlessly in low-message-rate situations. With long-polling, the browser sends a request to the server and the server keeps the request open for a set period of time. When you have a high message-volume, long-polling does not provide any substantial performance improvements over traditional polling. REAL-TIME AND HTTP
With streaming, the browser sends a complete request, but the server sends and maintains an open response that is continuously updated and kept open indefinitely (or for a set period of time). Streaming is still encapsulated in HTTP, intervening firewalls and proxy servers may choose to buffer the response increasing the latency of the message delivery. All of these methods for providing real-time data involve HTTP request and response headers, which contain lots of additional, unnecessary header data and introduce latency REAL-TIME AND HTTP
THE WEBSOCKET HANDSHAKE
A DRAMATIC REDUCTION IN UNNECESSARY NETWORK TRAFFIC AND LATENCY
LATENCY COMPARISION
Browser support for HTML5 WebSocket Checking for Browser Support if (window.WebSocket) { // support Websocket } else { // not support } BROWSER SUPPORT BrowserDetails ChromeSupported in version 4+ FirefoxSupported in version 4+ Internet ExplorerNot supported yet OperaNot supported yet SafariSupported in version 5+
Creating a WebSocket url = "ws://localhost:8080/echo"; w = new WebSocket(url); Add Event Listeners w.onopen = function() { log("open"); w.send("thank you for accepting this websocket request"); } w.onmessage = function(e) { log(e.data); } w.onclose = function(e) { log("closed"); } Sending Message document.getElementById("sendButton").onclick = function() { w.send(document.getElementById("inputMessage").value); } BASIC API USAGE
A Simple Java WebSocket Server Compile WebSocket Server Example javac -cp dist/WebSocket.jar example/ChatServer.java Run WebSocket Server java -cp dist/WebSocket.jar;example ChatServer WEBSOCKET SERVER
function connectServer() { var url = "ws://localhost:8887"; socket = new WebSocket(url); socket.onopen = function() { updateSocketStatus("Connected to WebSocket server"); } socket.onmessage = function(e) { updateSocketStatus("Update message: " + e.data); } function sendMessage() { var message = document.getElementById("sendMessage").value; socket.send(message); } document.getElementById("connectButton").addEventListener("click", connectServer); document.getElementById("sendMsgButton").addEventListener("click", sendMessage); A WEBSOCKET CHATROOM