ตัวอย่างการใช้งาน Socket.io รวมกับ NodeJs และ Express JS ในการสร้างเว็บแอพพลิเคชันประเภท Live Chat แบบ Real-Time อย่างง่าย
บทเรียนก่อนหน้านี้เราได้พัฒนา Single Page Website ด้วย ExpressJS และ NodeJS ใน
https://www.daydev.com/developer/single-page-application-node-js-and-express-js.html
รอบนี้เราจะเอาบทเรียนง่ายๆ ที่ทาง Socket.io ได้นำมาช่วยเหลือในการพัฒนาแอพพลิเคชัน Live Chat บนเว็บบราวเซอร์กัน ตามรูปแบบ Stack ทั้งหมด
เริ่มต้นให้เราเตรียมพร้อม Directory ที่เราจะทำงานขึ้นมาให้เรียบร้อยแล้ว เปิด Command Prompt หรือ Terminal ขึ้นมาครับ
ทำการทดสอบ เวอร์ชันของ npm ก่อน ด้วย
npm -v
ทำการสร้าง Package.json ของเราขึ้นมาก่อน โดยคำสั่งต่อไปนี้
npm init
กรอกข้อมูลทั้งหมดลงไปตามสิ่งที่เราอยากให้เป็นครับ ในตัวอย่างของผมผมเลือกส่วนนี้
จะได้ package.json ตามนี้ครับ
ทำการตกลงโดย yes ซะให้เรียบร้อยแล้วต่อมาให้เราติดตั้ง ExpressJS ลงใน Project ของเราครับ โดยใช้คำสั่ง
npm install --save [email protected]
หรือ
npm install express --save
ระบบจะสร้าง Project ทั้งหมดที่เราต้องใช้งานในการพัฒนาแอพพลิเคชันให้โดยทันที
ไปที่ไฟล์ index.js ใน path ‘directory/node_modules/express/’ แก้ไขโดยใส่คำสั่งต่อไปนี้
module.exports = require('./lib/express'); var myApp = require('express')(); var http = require('http').Server(myApp); var socketIO = require('socket.io')(http); myApp.get('/',function(request,response){ res.send('<h1>My Application</h1>'); }); http.listen(3000, function(){ console.log('listening *.3000'); });
ทดสอบแอพพลิเคชันของเราว่าทำงานถูกต้องไหมโดยรันคำสั่งต่อไปนี้บน Terminal
node index.js
เปิด Browser ขึ้นมาให้วิ่งที่ http://localhost:3000
สร้างไฟล์ Template ชื่อว่า index.html ขึ้นมาใหม่ใน Path เดียวกับ index.js โดยออกแบบดังนี้
<!doctype html> <html> <head> <title>Socket.IO Example</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font: 13px Helvetica, Arial; } form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; } form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; } form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; } #messages { list-style-type: none; margin: 0; padding: 0; } #messages li { padding: 5px 10px; } #messages li:nth-child(odd) { background: #eee; } </style> </head> <body> <ul id="messages"></ul> <form action=""> <input id="m" autocomplete="off" /><button>Send</button> </form> </body> </html>
แก้ไขไฟล์ index.js ใหม่ให้เรียก Template ของ index.html ไปแสดงผลแทนหน้าแอพพลิเคชัน
module.exports = require('./lib/express'); var myApp = require('express')(); var http = require('http').Server(myApp); var socketIO = require('socket.io')(http); myApp.get('/',function(request,response){ response.sendFile(__dirname + '/index.html'); }); http.listen(3000, function(){ console.log('listening *.3000'); });
รันคำสั่ง node index.js ใหม่ (กด Ctrl C ยกเลิกก่อนทุกครั้ง)
จะได้หน้าตาดังนี้ เป็นหน้าตาของ Live Chat คือมีพื้นที่แสดงข้อความในห้องแชท และมีกล่องใส่ Text พร้อมปุ่ม Send ต่อมาให้เราติดตั้ง Socket.io เพื่อสร้าง Socket ในการรับค่า state ของ Server เวลามีการ Chat ไปมาแบบ Real-Time:
npm install socket.io --save
ระบบจะทำการ Generate โครงสร้างของไฟล์ Library ให้ครับ
สร้าง Connected state ผ่าน Socket.io เราต้องมีการรับค่าว่า Client หรือหน้าจอ chat ของผู้ใช้งานพร้อมแล้ว ให้ทำการแจ้งต่อ Server ดังนั้นต้องมีการเพิ่ม connected State เข้ามาครับ ให้ไปเพิ่มที่ index.js ดังนี้
socketIO.on('connection', function(socket){ console.log('Connected!'); socket.on('disconnect', function(){ console.log('Someone Leave the Chat'); }); socket.on('chat message', function(msg){ console.log('Message: ' + msg); socketIO.emit('chat message', msg); }); });
เป็นการบอกว่า หากมีหน้าต่าง Chat โผล่ขึ้นมาโดยเปิดไปที่ http://localhost:3000 จะมีข้อความบน Server ว่า connected ผ่าน Console.log
console.log('Connected!');
และหน้ามีการผิดหน้าต่าง chat ไปจะส่งข้อความว่า “Someone Leave the Chat” และอัพเด็ต State ของ Server ว่า ‘disconnect’ กลับไปผ่านทาง Socket
socket.on('disconnect', function(){ console.log('Someone Leave the Chat'); });
เพิ่มเติม jQuery เล็กน้อยใน index.html (หน้า Template) ก่อนปิด </body>
<script src="/socket.io/socket.io.js"></script> <script> var socket = io(); </script>
ทดสอบ
ส่วนของการส่ง ข้อความไปมาระหว่างผู้ใช้งานผ่า Socket.io บน Server State ให้เราใช้ส่วนต่อไปนี้ในการส่งข้อความไปมาครับ
socket.on('chat message', function(msg){ console.log('Message: ' + msg); socketIO.emit('chat message', msg); });
เป็นการเพิ่ม State ชื่อ “chat message” ให้ Server เข้าใจและเมื่อพิมพ์อะไรไปจะส่งไปแสดงผลผ่าน Console ของ Socket ก่อน เราต้องเพิ่มหน้าการทำงานด้วย jQuery เล็กน้อยใน index.html (หน้า Template) ก่อนปิด </body>
<script src="/socket.io/socket.io.js"></script> <script src="http://code.jquery.com/jquery-1.11.1.js"></script> <script> var socket = io(); $('form').submit(function(){ socket.emit('chat message', $('#m').val()); $('#m').val(''); return false; }); </script>
ทดสอบโดยการส่งค่าไปมา
ข้อความจะปรากฏบน Console log ของ ระบบ ต่อมาเราจะแสดงผลที่ส่วนของ Client แล้ว ให้ไปแก้ไขที่ index.html (หน้า Template) เพิ่ม code jQuery เข้าไปดังนี้
<script src="/socket.io/socket.io.js"></script> <script src="http://code.jquery.com/jquery-1.11.1.js"></script> <script language="javascript"> var socket = io(); $('form').submit(function(){ socket.emit('chat message', $('#m').val()); $('#m').val(''); return false; }); socket.on('chat message', function(msg){ $('#messages').append($('<li>').text(msg)); }); </script>
ทดสอบการทำงาน ส่งค่าไปมา จะมีการเขียน <li> ด้วยตัวแปร msg ที่ส่งไปมาบน Socket.io
ตกแต่งด้วย Material Design Lite ของ Google เล็กน้อยเพื่อความสวยงาม ไฟล์ index.html จะเป็นดังนี้
<!doctype html> <html> <head> <title>Socket.IO Example</title> <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"> <link rel="stylesheet" href="https://code.getmdl.io/1.1.1/material.indigo-pink.min.css"> <script defer src="https://code.getmdl.io/1.1.1/material.min.js"></script> <style> .demo-list-icon {width: 100%;} #messages li:nth-child(odd) { background: #eee; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font: 13px Helvetica, Arial; } form { background: #eee; padding: 3px; position: fixed; bottom: 0; width: 100%; } form input { border: 0; padding: 10px; width: 85%; margin-right: .5%; } form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; } </style> </head> <body> <ul id="messages" class="demo-list-icon mdl-list"></ul> <form action=""> <input id="m" autocomplete="off" /> <button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect mdl-button--accent">Send</button> </form> <script src="/socket.io/socket.io.js"></script> <script src="http://code.jquery.com/jquery-1.11.1.js"></script> <script language="javascript"> var socket = io(); $('form').submit(function(){ socket.emit('chat message', $('#m').val()); $('#m').val(''); return false; }); socket.on('chat message', function(msg){ $('#messages').append($('<li class="mdl-list__item"><i class="material-icons mdl-list__item-icon">person</i>').text(msg)); }); </script> </body> </html>
ไฟล์ index.js จะเป็นดังนี้
module.exports = require('./lib/express'); var myApp = require('express')(); var http = require('http').Server(myApp); var socketIO = require('socket.io')(http); myApp.get('/',function(request,response){ response.sendFile(__dirname + '/index.html'); }); http.listen(3000, function(){ console.log('listening *.3000'); }); socketIO.on('connection', function(socket){ console.log('Connected!'); socket.on('disconnect', function(){ console.log('Someone Leave the Chat'); }); socket.on('chat message', function(msg){ console.log('Message: ' + msg); socketIO.emit('chat message', msg); }); });
เราก็จะมีแอพพลิเคชัน Live Chat สวยๆ ตามภาพตัวอย่าง ลองไปทำเล่นกันดูนะครับ
Ref: node.js, express js, socket.io