作一個簡單的HTTP服務器, 實現幾個功能html
// 一個小例子. const http = require('http') const fs = require('fs') const getTitles = (res) => { fs.readFile(__dirname + '\\titles.json', (err, data) => { if (err) return hadError(err, res) getTemplate(JSON.parse(data.toString()), res) }) } const getTemplate = (titles, res) => { fs.readFile(__dirname + '\\template.html', (err, data) => { if (err) return hadError(err, res) formatHTML(titles, data.toString(), res) }) } const formatHTML = (titles, tmpl, res) => { const html = tmpl.replace('%', titles.join('</li><li>')) res.writeHead(200, {'Content-Type': 'text/html'}) res.end(html) } const hadError = (err, res) => { console.error(err) res.end('Server Error') } http.createServer((req, res) => { if (req.url = '/') { getTitles(res) } }).listen(8080, '127.0.0.1')
事件發射器會觸發事件, 而且在那些事件被觸發時能處理它們.
好比HTTP服務器, TCP服務器和流. 都被作成了事件發射器json
事件是經過監聽器進行處理的.
監聽器是與事件相關聯, 每當有事件出現時, 就會被觸發的回調函數
例如Node中 TCP socket, 它有一個data事件, 每當socket有新數據的時候就會觸發瀏覽器
socket.on('data', handleData)
const net = require('net') const server = net.createServer((socket) => { socket.on('data', data => { console.log(data.toString()) socket.write(data) }) }) server.listen(8888)
EventEmitter是一個事件發射器
咱們能夠經過EventEmitter的實例服務器
註冊監聽器異步
eventEmitter.on()
觸發事件socket
eventEmitter.emit()
所以, 寫出一個小demo函數
const EventEmitter = require('events').EventEmitter const channel = new EventEmitter() channel.on('join', () => { // 註冊監聽, 監聽join事件, 事件被觸發後調用後面的函數 console.log('welcome!') }) channel.emit('join') // 發射事件
注: 事件名稱能夠是任意字符串. 只有error事件是特殊的ui
發佈/訂閱
系統(聊天室)const events = require('events') const net = require('net') const channel = new events.EventEmitter() channel.clients = {} channel.subscriptions = {} channel.on('join', function(id, client) { console.log(`監聽到${id}號玩家加入遊戲`) this.clients[id] = client this.subscriptions[id] = (senderId, msg) => { if (id != senderId) { this.clients[id].write(msg) console.log(`${id}號玩家收到廣播消息${msg}`) } } this.on('boardcast', this.subscriptions[id]) }) let id = 0 const server = net.createServer((client) => { const gamer = ++id console.log(`玩家${gamer}進入服務器`) channel.emit('join', gamer, client) client.on('data', (data) => { console.log(`${gamer}玩家發送廣播消息: ${data.toString()} .`) channel.emit('boardcast', gamer, data.toString()) }) }) server.listen(8888)
上面一版的代碼會出現問題, 由於咱們給每一個用戶都綁定了監聽器, 當用戶退出的時候, 監聽器沒有關閉, 就會出現錯誤this
因此咱們要在用戶退出的時候, 刪去與之對應的監聽器url
// ... channel.on('leave', function(id) { console.log(`${id}號用戶已經退出房間`) channel.removeListener('broadcast', this.subscriptions[id]) }) // ... let id = 0 const server = net.createServer((client) => { const user = ++id console.log(`用戶${user}進入服務器`) channel.emit('join', user, client) client.on('data', (data) => { console.log(`${user}用戶發送廣播消息: ${data.toString()} .`) channel.emit('broadcast', user, data.toString()) }) client.on('close', () => { channel.emit('leave', user) }) })