0%

socket.io如何串接express的app.js

Simple Twitter 挑戰功能
完成練習專案
Github

socket.io 伺服器檔案怎麼與express伺服器app.js拆開

起初在本地的時候,是在app.js之中載入寫好的socket.io伺服器

1
2
3
4
5
...
const app = express()
const SESSION_SECRET = 'simpleTwitter'
require('./config/server-socket.io') // 加在了這個地方
...

然後在 server-socket.io.js 檔案中

1
2
const { Server } = require('socket.io')
const io = new Server(3200, { /* options */ })

在HTML需載入CDN引用

1
2
3
<script src="https://cdn.socket.io/4.5.0/socket.io.min.js"
integrity="sha384-7EyYLQZgWBi67fBtVxw60/OWl1kjsfrPFcaU0pp0nAh+i8FD068QogUvg85Ewy1k" crossorigin="anonymous"></script>
<script src="/javascripts/chatroom-socket-io.js"></script>

在chatroom-socket-io.js 檔中連結io伺服器

1
2
3
4
const userId = 1
// query可以把物件帶入socket.io伺服器
// 後端使用socket.handshake.query.userId 可以取得
const socket = io('http://localhost:3200', { query: { userId } })

但當開啟頁面時卻出現了連接不到伺服器的狀況

後來發現若在本地端這樣的架構,客戶端是經由 express伺服器Port:3000,再進到
io Server Port:3200,所以伺服器這邊會接不到客戶端,所以需要加上cros

server-socket.io.js 檔案中

1
2
3
4
const { Server } = require('socket.io')
const io = new Server(3200, {
cors: { origin: ['http://localhost:3000'] } // 可以帶入多組路由
})

第一次連不上的問題就解開了,可是到了要上傳heroku的時候,這樣寫死port的方式,heroku是沒辦法使用的。

所以看了heroku及socket.io官方文檔後,socket.io伺服器,若要掛勾express伺服器的話,必須先建立一個http伺服器,並將express當參數載入,之後再監聽這組http伺服器,而socket.io則是連向這組http伺服器。

所以按步驟需要做以下改動

在app.js檔案下,取消require

1
2
3
4
5
6
7
8
9
10
11
...
const app = express()
const SESSION_SECRET = 'simpleTwitter'
// require('./config/server-socket.io') // 這行取消
// const port = process.env.PORT || 3000 // port也不需要了
...
// 以下伺服器監聽全刪除
app.listen(port, () => {
console.info(`Example app listening on http://localhost:${port}`)
})
// 以上監聽全刪

在server-socket.io.js 檔案中

1
2
3
4
5
6
7
8
9
10
11
12
const app = require('./app') // 載入app.js
const { createServer } = require('http') // 載入http工具
const { Server } = require('socket.io') // 載入socket.io
const httpServer = createServer(app) // 創建httpServer並把app作為參數
const port = process.env.PORT || 3000 // 加上 port
// 最後io伺服器連向httpServer, cros也不需要了
const io = new Server(httpServer, { /* options */ })
...
// 最後啟動監聽伺服器
httpServer.listen(port, () => {
console.info(`Example app listening on http://localhost:${port}`)
})

負責客戶端的chatroom-socket-io.js 中

1
2
3
const userId = Number(chatroomMenu.dataset.userid)
// 把第一個原本http://localhost:3200的path參數拿掉
const socket = io({ query: { userId } })

最後 package.json檔案腳本別忘了改成啟動server-socket.io.js
heroku的Procfile也要改成啟動server-socket.io.js

Welcome to my other publishing channels