เซิร์ฟเวอร์ NodeJs สำหรับการออกอากาศ Laravel Echo ด้วย Socket.io
จำเป็นต้องมีสิ่งต่อไปนี้เพื่อให้ทำงานได้อย่างถูกต้อง
ข้อมูลเพิ่มเติมเกี่ยวกับการออกอากาศด้วย Laravel สามารถพบได้ในเอกสารอย่างเป็นทางการ: https://laravel.com/docs/master/broadcasting
ติดตั้งแพ็คเกจ npm ทั่วโลกด้วยคำสั่งต่อไปนี้:
$ npm install -g laravel-echo-server
รันคำสั่ง init ในไดเร็กทอรีโปรเจ็กต์ของคุณ:
$ laravel-echo-server init
เครื่องมือ cli จะช่วยคุณตั้งค่าไฟล์ laravel-echo-server.json ในไดเรกทอรีรากของโปรเจ็กต์ของคุณ ไฟล์นี้จะถูกโหลดโดยเซิร์ฟเวอร์ระหว่างการเริ่มต้นระบบ คุณสามารถแก้ไขไฟล์นี้ในภายหลังเพื่อจัดการการกำหนดค่าเซิร์ฟเวอร์ของคุณ
เซิร์ฟเวอร์ Laravel Echo เปิดเผย http API แบบเบาเพื่อใช้งานฟังก์ชันการออกอากาศ เพื่อวัตถุประสงค์ด้านความปลอดภัย การเข้าถึงตำแหน่งข้อมูลเหล่านี้จากผู้อ้างอิง http จะต้องได้รับการรับรองความถูกต้องด้วยรหัสแอปและคีย์ สิ่งนี้สามารถสร้างขึ้นได้โดยใช้คำสั่ง cli:
$ laravel-echo-server client:add APP_ID
หากคุณเรียกใช้ client:add
โดยไม่มีอาร์กิวเมนต์ app id อาร์กิวเมนต์จะถูกสร้างขึ้นสำหรับคุณ หลังจากรันคำสั่งนี้ รหัสไคลเอ็นต์และคีย์จะแสดงและจัดเก็บไว้ในไฟล์ laravel-echo-server.json
ในตัวอย่างนี้ คำขอจะได้รับอนุญาตตราบใดที่ระบุรหัสแอปและคีย์พร้อมกับคำขอ http
Request Headers
Authorization: Bearer skti68i...
or
http://app.dev:6001/apps/APP_ID/channels?auth_key=skti68i...
คุณสามารถลบไคลเอนต์ด้วย laravel-echo-server client:remove APP_ID
ในไดเร็กทอรีรากของโปรเจ็กต์ของคุณ ให้รัน
$ laravel-echo-server start
ในไดเร็กทอรีรากของโปรเจ็กต์ของคุณ ให้รัน
$ laravel-echo-server stop
แก้ไขการกำหนดค่าเริ่มต้นของเซิร์ฟเวอร์โดยการเพิ่มตัวเลือกให้กับไฟล์ laravel-echo-server.json ของคุณ
ชื่อ | ค่าเริ่มต้น | คำอธิบาย |
---|---|---|
apiOriginAllow | {} | การกำหนดค่าเพื่ออนุญาตให้เข้าถึง API ผ่าน CORS ตัวอย่าง |
authEndpoint | /broadcasting/auth | เส้นทางที่รับรองความถูกต้องของช่องส่วนตัว |
authHost | http://localhost | โฮสต์ของเซิร์ฟเวอร์ที่ตรวจสอบช่องทางส่วนตัวและการแสดงตน |
database | redis | ฐานข้อมูลที่ใช้ในการจัดเก็บข้อมูลที่ควรคงอยู่ เช่น สมาชิกของช่องทางการแสดงตน ขณะนี้ตัวเลือกคือ redis และ sqlite |
databaseConfig | {} | ตัวอย่างการกำหนดค่าสำหรับไดรเวอร์ฐานข้อมูลต่างๆ |
devMode | false | เพิ่มการบันทึกเพิ่มเติมเพื่อวัตถุประสงค์ในการพัฒนา |
host | null | โฮสต์ของเซิร์ฟเวอร์ socket.io เช่น app.dev . null จะยอมรับการเชื่อมต่อบนที่อยู่ IP ใด ๆ |
port | 6001 | พอร์ตที่เซิร์ฟเวอร์ socket.io ควรทำงาน |
protocol | http | ต้องเป็น http หรือ https |
sslCertPath | '' | เส้นทางไปยังใบรับรอง SSL ของเซิร์ฟเวอร์ของคุณ |
sslKeyPath | '' | เส้นทางไปยังคีย์ SSL ของเซิร์ฟเวอร์ของคุณ |
sslCertChainPath | '' | เส้นทางไปยังกลุ่มใบรับรอง SSL ของเซิร์ฟเวอร์ของคุณ |
sslPassphrase | '' | วลีรหัสผ่านที่ใช้สำหรับใบรับรอง (ถ้ามี) |
socketio | {} | ตัวเลือกในการส่งผ่านไปยังอินสแตนซ์ socket.io (ตัวเลือกที่มี) |
subscribers | {"http": true, "redis": true} | อนุญาตให้ปิดการใช้งานสมาชิกเป็นรายบุคคล สมาชิกที่มีอยู่: http และ redis |
หากพบไฟล์ .env ในไดเร็กทอรีเดียวกันกับไฟล์ laravel-echo-server.json คุณสามารถแทนที่ตัวเลือกต่อไปนี้ได้:
authHost
: LARAVEL_ECHO_SERVER_AUTH_HOST
หมายเหตุ : ตัวเลือกนี้จะถอยกลับไปที่ตัวเลือก LARAVEL_ECHO_SERVER_HOST
เป็นค่าเริ่มต้น หากตั้งค่าไว้ในไฟล์ .envhost
: LARAVEL_ECHO_SERVER_HOST
port
: LARAVEL_ECHO_SERVER_PORT
devMode
: LARAVEL_ECHO_SERVER_DEBUG
databaseConfig.redis.host
: LARAVEL_ECHO_SERVER_REDIS_HOST
databaseConfig.redis.port
: LARAVEL_ECHO_SERVER_REDIS_PORT
databaseConfig.redis.password
: LARAVEL_ECHO_SERVER_REDIS_PASSWORD
protocol
: LARAVEL_ECHO_SERVER_PROTO
sslKeyPath
: LARAVEL_ECHO_SERVER_SSL_KEY
sslCertPath
: LARAVEL_ECHO_SERVER_SSL_CERT
sslPassphrase
: LARAVEL_ECHO_SERVER_SSL_PASS
sslCertChainPath
: LARAVEL_ECHO_SERVER_SSL_CHAIN
หมายเหตุ: ขณะนี้ไลบรารีนี้รองรับเฉพาะการให้บริการจาก http หรือ https เท่านั้น ไม่ใช่ทั้งสองอย่าง
หากคุณกำลังประสบปัญหาในการใช้งาน SSL กับแพ็คเกจนี้ คุณสามารถดูการใช้โมดูลพร็อกซีภายใน Apache หรือ NginX โดยพื้นฐานแล้ว แทนที่จะเชื่อมต่อการรับส่งข้อมูล websocket ของคุณกับ https://yourserver.dev:6001/socket.io?..... และพยายามรักษาความปลอดภัย คุณสามารถเชื่อมต่อการรับส่งข้อมูล websocket ของคุณกับ https://yourserver.dev/socket .io เบื้องหลัง โมดูลพร็อกซีของ Apache หรือ NginX จะได้รับการกำหนดค่าให้สกัดกั้นคำขอสำหรับ /socket.io และเปลี่ยนเส้นทางคำขอเหล่านั้นไปยังเซิร์ฟเวอร์ echo ของคุณภายในผ่าน non-ssl บนพอร์ต 6001 ซึ่งจะทำให้การรับส่งข้อมูลทั้งหมดได้รับการเข้ารหัสระหว่างเบราว์เซอร์และเว็บ เนื่องจากเว็บเซิร์ฟเวอร์ของคุณจะยังคงทำการเข้ารหัส/ถอดรหัส SSL สิ่งเดียวที่ไม่ปลอดภัยคือการรับส่งข้อมูลระหว่างเว็บเซิร์ฟเวอร์และเซิร์ฟเวอร์ Echo ของคุณ ซึ่งอาจยอมรับได้ในหลายกรณี
#the following would go within the server{} block of your web server config
location /socket.io {
proxy_pass http://laravel-echo-server:6001; #could be localhost if Echo and NginX are on the same box
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
RewriteCond %{REQUEST_URI} ^/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /(.*) ws://localhost:6001/$1 [P,L]
ProxyPass /socket.io http://localhost:6001/socket.io
ProxyPassReverse /socket.io http://localhost:6001/socket.io
ไดเร็กทอรีการทำงานที่ laravel-echo-server
จะค้นหาไฟล์การกำหนดค่า laravel-echo-server.json
สามารถส่งผ่านไปยังคำสั่ง start
ผ่านพารามิเตอร์ --dir
ดังนี้: laravel-echo-server start --dir=/var/www/html/example.com/configuration
Laravel Echo Server สมัครรับกิจกรรมขาเข้าด้วยสองวิธี: Redis & Http
แอปพลิเคชันหลักของคุณสามารถใช้ Redis เพื่อเผยแพร่กิจกรรมไปยังช่องต่างๆ เซิร์ฟเวอร์ Laravel Echo จะสมัครสมาชิกช่องเหล่านั้นและเผยแพร่ข้อความเหล่านั้นผ่าน socket.io
เมื่อใช้ Http คุณยังสามารถเผยแพร่กิจกรรมไปยัง Laravel Echo Server ในลักษณะเดียวกับที่คุณทำกับ Redis โดยการส่ง channel
และ message
ไปยังจุดสิ้นสุดการออกอากาศ คุณต้องสร้างคีย์ API ตามที่อธิบายไว้ในส่วนไคลเอ็นต์ API และระบุคีย์ API ที่ถูกต้อง
ขอจุดสิ้นสุด
POST http://app.dev:6001/apps/your-app-id/events?auth_key=skti68i...
ขอเนื้อความ
{
"channel" : " channel-name " ,
"name" : " event-name " ,
"data" : {
"key" : " value "
},
"socket_id" : " h3nAdb134tbvqwrg "
}
channel - ชื่อของช่องที่จะถ่ายทอดกิจกรรมไป สำหรับช่องส่วนตัวหรือการแสดงตน ให้นำหน้า private-
หรือ presence-
- ช่อง - แทนที่จะเป็นช่องเดียว คุณสามารถออกอากาศไปยังอาร์เรย์ของช่องได้ด้วย 1 คำขอ ชื่อ - สตริงที่แสดงถึงคีย์เหตุการณ์ภายในแอปของคุณ data - ข้อมูลที่คุณต้องการออกอากาศไปยังช่อง socket_id (เป็นทางเลือก) - ID ซ็อกเก็ตของผู้ใช้ที่เริ่มต้นเหตุการณ์ เมื่อปรากฏ เซิร์ฟเวอร์จะ "เผยแพร่ไปยังผู้อื่น" เท่านั้น
สมาชิก HTTP เข้ากันได้กับสมาชิก Laravel Pusher เพียงกำหนดค่าโฮสต์และพอร์ตสำหรับเซิร์ฟเวอร์ Socket.IO ของคุณ จากนั้นตั้งค่ารหัสแอปและป้อน config/broadcasting.php ไม่จำเป็นต้องมีความลับ
' pusher ' => [
' driver ' => ' pusher ' ,
' key ' => env ( ' PUSHER_KEY ' ),
' secret ' => null ,
' app_id ' => env ( ' PUSHER_APP_ID ' ),
' options ' => [
' host ' => ' localhost ' ,
' port ' => 6001 ,
' scheme ' => ' http '
],
],
ตอนนี้คุณสามารถส่งกิจกรรมโดยใช้ HTTP โดยไม่ต้องใช้ Redis นอกจากนี้ยังช่วยให้คุณใช้ Pusher API เพื่อแสดงรายการช่อง/ผู้ใช้ตามที่อธิบายไว้ในไลบรารี Pusher PHP
HTTP API เปิดเผยตำแหน่งข้อมูลที่ช่วยให้คุณสามารถรวบรวมข้อมูลเกี่ยวกับเซิร์ฟเวอร์และช่องสัญญาณที่ทำงานอยู่
สถานะ รับจำนวนไคลเอ็นต์ทั้งหมด เวลาทำงานของเซิร์ฟเวอร์ และการใช้หน่วยความจำ
GET /apps/:APP_ID/status
รายการ ช่อง ของทุกช่อง
GET /apps/:APP_ID/channels
Channel รับข้อมูลเกี่ยวกับช่องใดช่องหนึ่ง
GET /apps/:APP_ID/channels/:CHANNEL_NAME
ผู้ใช้ช่อง รายชื่อผู้ใช้ในช่อง
GET /apps/:APP_ID/channels/:CHANNEL_NAME/users
คุณสามารถระบุการเข้าถึงข้ามโดเมนได้ในไฟล์ laravel-echo-server.json โดยเปลี่ยน allowCors
ใน apiOriginAllow
เป็น true
จากนั้น คุณสามารถตั้งค่า CORS Access-Control-Allow-Origin, Access-Control-Allow-Methods เป็นสตริงที่คั่นด้วยเครื่องหมายจุลภาค (GET และ POST จะเปิดใช้งานตามค่าเริ่มต้น) และ Access-Control-Allow-Headers ที่ API สามารถรับได้
ตัวอย่างด้านล่าง:
{
"apiOriginAllow" :{
"allowCors" : true ,
"allowOrigin" : " http://127.0.0.1 " ,
"allowMethods" : " GET, POST " ,
"allowHeaders" : " Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id "
}
}
ซึ่งจะทำให้คุณสามารถส่งคำขอไปยัง API ผ่าน AJAX จากแอปที่อาจทำงานบนโดเมนเดียวกันแต่ใช้พอร์ตอื่นหรือโดเมนอื่นโดยสิ้นเชิง
เพื่อคงข้อมูลช่องทางการแสดงตน มีการรองรับการใช้ Redis หรือ SQLite เป็นที่จัดเก็บคีย์/ค่า คีย์คือชื่อช่อง และค่าคือรายชื่อสมาชิกของช่องการแสดงตน
ไดรเวอร์ฐานข้อมูลแต่ละตัวอาจได้รับการกำหนดค่าในไฟล์ laravel-echo-server.json ภายใต้คุณสมบัติ databaseConfig
ตัวเลือกต่างๆ จะถูกส่งผ่านไปยังผู้ให้บริการฐานข้อมูล ดังนั้นนักพัฒนาจึงมีอิสระในการตั้งค่าเหล่านี้ได้ตามต้องการ
ตัวอย่างเช่น หากคุณต้องการส่งการกำหนดค่าแบบกำหนดเองไปยัง Redis ให้ทำดังนี้
{
"databaseConfig" : {
"redis" : {
"port" : " 3001 " ,
"host" : " redis.app.dev " ,
"keyPrefix" : " my-redis-prefix "
}
}
}
หมายเหตุ: ไม่ควรใช้รูปแบบ (http/https ฯลฯ) สำหรับที่อยู่โฮสต์
ดูรายการตัวเลือก Redis ทั้งหมดได้ที่นี่
ตัวอย่างเช่น หากคุณต้องการใช้ redis-sentinel คุณจะต้องผ่านการกำหนดค่าที่กำหนดเอง :
"databaseConfig" : {
"redis" : {
"sentinels" : [
{
"host" : " redis-sentinel-0 " ,
"port" : 26379
},
{
"host" : " redis-sentinel-1 " ,
"port" : 26379
}
{
"host" : " redis-sentinel-2 " ,
"port" : 26379
}
],
"name" : " mymaster " ,
"sentinelPassword" : " redis-password "
},
},
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดค่า Redis Sentinel คุณสามารถตรวจสอบได้
ด้วย SQLite คุณอาจสนใจที่จะเปลี่ยนเส้นทางที่เก็บฐานข้อมูล
{
"databaseConfig" : {
"sqlite" : {
"databasePath" : " /path/to/laravel-echo-server.sqlite "
}
}
}
หมายเหตุ 1: เส้นทางนี้สัมพันธ์กับรูทของแอปพลิเคชันของคุณ ไม่ใช่ระบบของคุณ
หมายเหตุ 2: จำเป็นต้องใช้ node-sqlite3 สำหรับฐานข้อมูลนี้ กรุณาติดตั้งก่อนใช้งาน
npm install sqlite3 -g
เมื่อผู้ใช้เข้าร่วมช่องทางการแสดงตน ข้อมูลการตรวจสอบสิทธิ์ของช่องทางการแสดงตนจะถูกจัดเก็บไว้โดยใช้ Redis
แม้ว่าช่องทางการแสดงตนจะมีรายชื่อผู้ใช้ ก็จะมีกรณีที่ผู้ใช้เข้าร่วมช่องทางการแสดงตนหลายครั้ง ตัวอย่างเช่น เหตุการณ์นี้จะเกิดขึ้นเมื่อเปิดแท็บเบราว์เซอร์หลายแท็บ ในสถานการณ์นี้เหตุการณ์ "เข้าร่วม" และ "ออก" จะถูกส่งไปที่อินสแตนซ์แรกและสุดท้ายของผู้ใช้เท่านั้น
ทางเลือก คุณสามารถกำหนดค่า laravel-echo-server เพื่อเผยแพร่เหตุการณ์ในแต่ละการอัปเดตไปยังช่องทางการแสดงตน โดยการตั้งค่า databaseConfig.publishPresence
เป็น true
:
{
"database" : " redis " ,
"databaseConfig" : {
"redis" : {
"port" : " 6379 " ,
"host" : " localhost "
},
"publishPresence" : true
}
}
คุณสามารถใช้การรวม Redis ของ Laravel เพื่อทริกเกอร์รหัสแอปพลิเคชันได้จากที่นั่น:
Redis :: subscribe ([ ' PresenceChannelUpdated ' ], function ( $ message ) {
var_dump ( $ message );
});
ดูเอกสารประกอบ Laravel อย่างเป็นทางการสำหรับข้อมูลเพิ่มเติม https://laravel.com/docs/master/broadcasting#introduction
คุณสามารถรวมไลบรารีไคลเอ็นต์ socket.io ได้จากเซิร์ฟเวอร์ที่รันอยู่ ตัวอย่างเช่น หากเซิร์ฟเวอร์ของคุณทำงานที่ app.dev:6001
คุณควรจะสามารถเพิ่มแท็กสคริปต์ลงใน html ของคุณได้ดังนี้:
<script src="//app.dev:6001/socket.io/socket.io.js"></script>
หมายเหตุ: เมื่อใช้ไลบรารีไคลเอ็นต์ socket.io จากเซิร์ฟเวอร์ที่รันอยู่ อย่าลืมตรวจสอบว่าตัวแปรโกลบอล io
ถูกกำหนดไว้ก่อนที่จะสมัครรับเหตุการณ์
µWebSockets เลิกใช้งานอย่างเป็นทางการแล้ว ขณะนี้ไม่มีการรองรับ µWebSockets ใน Socket.IO แต่อาจมีการรองรับ ClusterWS ใหม่เข้ามา ในขณะเดียวกัน Laravel Echo Server จะใช้ ws
engine เป็นค่าเริ่มต้นจนกว่าจะมีตัวเลือกอื่น