ไลบรารี PHP สำหรับการโต้ตอบกับ Pusher Channels HTTP API
ลงทะเบียนที่ https://pusher.com และใช้ข้อมูลรับรองแอปพลิเคชันภายในแอปของคุณดังที่แสดงด้านล่าง
สำหรับการรายงานปัญหา ข้อบกพร่อง และคำขอคุณสมบัติ โปรดเปิดคำขอดึงหรือเปิดปัญหาได้ตามสบาย หากคุณไม่ได้รับการตอบกลับทันเวลา โปรดตรวจสอบพอร์ทัลสนับสนุนของเรา
คุณสามารถรับไลบรารี Pusher Channels PHP ได้ผ่านทางแพ็คเกจผู้แต่งที่เรียกว่า pusher-php-server
ดูhttps://packagist.org/packages/pusher/pusher-php-server
$ composer require pusher/pusher-php-server
หรือเพิ่มใน composer.json
:
"require" : {
"pusher/pusher-php-server" : " ^7.2 "
}
จากนั้นเรียกใช้ composer update
ใช้ข้อมูลประจำตัวจากแอปพลิเคชัน Pusher Channels ของคุณเพื่อสร้างอินสแตนซ์ PusherPusher
ใหม่
$ app_id = ' YOUR_APP_ID ' ;
$ app_key = ' YOUR_APP_KEY ' ;
$ app_secret = ' YOUR_APP_SECRET ' ;
$ app_cluster = ' YOUR_APP_CLUSTER ' ;
$ pusher = new Pusher Pusher ( $ app_key , $ app_secret , $ app_id , [ ' cluster ' => $ app_cluster ]);
พารามิเตอร์ตัวที่สี่คืออาร์เรย์ $options
ตัวเลือกเพิ่มเติมคือ:
scheme
- เช่น http หรือ httpshost
- โฮสต์ เช่น api.pusherapp.com ไม่มีเครื่องหมายทับต่อท้ายport
- พอร์ต httppath
- คำนำหน้าเพื่อต่อท้ายเส้นทางคำขอทั้งหมด สิ่งนี้มีประโยชน์เฉพาะในกรณีที่คุณกำลังเรียกใช้ไลบรารีกับจุดสิ้นสุดที่คุณควบคุมเอง (เช่น พร็อกซีที่กำหนดเส้นทางตามคำนำหน้าเส้นทาง)timeout
- หมดเวลา HTTPuseTLS
- ตัวเลือกด่วนในการใช้โครงร่างของ https และพอร์ต 443cluster
- ระบุคลัสเตอร์ที่แอปพลิเคชันกำลังทำงานอยู่encryption_master_key_base64
- คีย์ยาว 32 ตัวอักษร คีย์นี้พร้อมกับชื่อช่องจะใช้เพื่อรับคีย์การเข้ารหัสต่อช่อง คีย์ต่อช่องจะใช้เข้ารหัสข้อมูลเหตุการณ์ในช่องที่เข้ารหัสตัวอย่างเช่น โดยค่าเริ่มต้น การโทรจะดำเนินการผ่าน HTTPS หากต้องการใช้ HTTP ธรรมดา คุณสามารถตั้งค่า useTLS เป็นเท็จ:
$ options = [
' cluster ' => $ app_cluster ,
' useTLS ' => false
];
$ pusher = new Pusher Pusher ( $ app_key , $ app_secret , $ app_id , $ options );
วิธีการบันทึกที่แนะนำคือการใช้ตัวบันทึกที่สอดคล้องกับ PSR-3 ที่ใช้ PsrLogLoggerInterface
วัตถุ Pusher
ใช้ PsrLogLoggerAwareInterface
ซึ่งหมายความว่าคุณเรียก setLogger(LoggerInterface $logger)
เพื่อตั้งค่าอินสแตนซ์ตัวบันทึก
// where $logger implements `LoggerInterface`
$ pusher -> setLogger ( $ logger );
ห้องสมุดนี้ใช้ Guzzle ภายในเพื่อโทรผ่าน HTTP คุณสามารถส่งอินสแตนซ์ Guzzle ของคุณเองไปยังตัวสร้าง Pusher:
$ custom_client = new GuzzleHttp Client ();
$ pusher = new Pusher Pusher (
$ app_key ,
$ app_secret ,
$ app_id ,
[],
$ custom_client
);
ซึ่งจะทำให้คุณสามารถผ่านมิดเดิลแวร์ของคุณเองได้ ดูตัวอย่างการทดสอบ
หากต้องการทริกเกอร์เหตุการณ์ในช่องสัญญาณตั้งแต่หนึ่งช่องขึ้นไป ให้ใช้ฟังก์ชัน trigger
$ pusher -> trigger ( ' my-channel ' , ' my_event ' , ' hello world ' );
$ pusher -> trigger ([ ' channel-1 ' , ' channel-2 ' ], ' my_event ' , ' hello world ' );
นอกจากนี้ยังสามารถส่งหลายเหตุการณ์ด้วยการเรียก API เพียงครั้งเดียว (สูงสุด 10 เหตุการณ์ต่อการโทรบนคลัสเตอร์หลายผู้เช่า):
$ batch = [];
$ batch [] = [ ' channel ' => ' my-channel ' , ' name ' => ' my_event ' , ' data ' => [ ' hello ' => ' world ' ]];
$ batch [] = [ ' channel ' => ' my-channel ' , ' name ' => ' my_event ' , ' data ' => [ ' myname ' => ' bob ' ]];
$ pusher -> triggerBatch ( $ batch );
ทั้ง trigger
และ triggerBatch
มีคู่กันแบบอะซิงโครนัสใน triggerAsync
และ triggerBatchAsync
ฟังก์ชั่นเหล่านี้คืนสัญญา Guzzle ซึ่งสามารถผูกมัดกับ ->then
:
$ promise = $ pusher -> triggerAsync ([ ' channel-1 ' , ' channel-2 ' ], ' my_event ' , ' hello world ' );
$ promise -> then ( function ( $ result ) {
// do something with $result
return $ result ;
});
$ final_result = $ promise -> wait ();
อาร์เรย์จะถูกแปลงเป็นรูปแบบ JSON โดยอัตโนมัติ:
$ array [ ' name ' ] = ' joe ' ;
$ array [ ' message_count ' ] = 23 ;
$ pusher -> trigger ( ' my_channel ' , ' my_event ' , $ array );
ผลลัพธ์ของสิ่งนี้จะเป็น:
" {'name': 'joe', 'message_count': 23} "
เพื่อหลีกเลี่ยงการซ้ำซ้อน คุณสามารถเลือกระบุรหัสซ็อกเก็ตของผู้ส่งในขณะที่ทริกเกอร์เหตุการณ์ได้:
$ pusher -> trigger ( ' my-channel ' , ' event ' , ' data ' , [ ' socket_id ' => $ socket_id ]);
$ batch = [];
$ batch [] = [ ' channel ' => ' my-channel ' , ' name ' => ' my_event ' , ' data ' => [ ' hello ' => ' world ' ], [ ' socket_id ' => $ socket_id ]];
$ batch [] = [ ' channel ' => ' my-channel ' , ' name ' => ' my_event ' , ' data ' => [ ' myname ' => ' bob ' ], [ ' socket_id ' => $ socket_id ]];
$ pusher -> triggerBatch ( $ batch );
คุณสามารถขอแอตทริบิวต์เกี่ยวกับช่องที่เผยแพร่ด้วยพารามิเตอร์ info
ได้:
$ result = $ pusher -> trigger ( ' my-channel ' , ' my_event ' , ' hello world ' , [ ' info ' => ' subscription_count ' ]);
$ subscription_count = $ result -> channels [ ' my-channel ' ]-> subscription_count ;
$ batch = [];
$ batch [] = [ ' channel ' => ' my-channel ' , ' name ' => ' my_event ' , ' data ' => [ ' hello ' => ' world ' ], ' info ' => ' subscription_count ' ];
$ batch [] = [ ' channel ' => ' presence-my-channel ' , ' name ' => ' my_event ' , ' data ' => [ ' myname ' => ' bob ' ], ' info ' => ' user_count,subscription_count ' ];
$ result = $ pusher -> triggerBatch ( $ batch );
foreach ( $ result -> batch as $ i => $ attributes ) {
echo " channel: { $ batch [ $ i ][ ' channel ' ]} , name: { $ batch [ $ i ][ ' name ' ]}" ;
if ( isset ( $ attributes -> subscription_count )) {
echo " , subscription_count: { $ attributes -> subscription_count }" ;
}
if ( isset ( $ attributes -> user_count )) {
echo " , user_count: { $ attributes -> user_count }" ;
}
echo PHP_EOL ;
}
หากข้อมูลของคุณได้รับการเข้ารหัสในรูปแบบ JSON แล้ว คุณสามารถหลีกเลี่ยงขั้นตอนการเข้ารหัสที่สองได้โดยการตั้งค่าอาร์กิวเมนต์ที่หกเป็นจริง เช่น:
$ pusher -> trigger ( ' my-channel ' , ' event ' , ' data ' , [], true );
ในการตรวจสอบสิทธิ์ผู้ใช้บน Pusher Channels บนแอปพลิเคชันของคุณ คุณสามารถใช้ฟังก์ชัน authenticateUser
ได้:
$ pusher -> authenticateUser ( ' socket_id ' , ' user-id ' );
สำหรับข้อมูลเพิ่มเติม โปรดดูการตรวจสอบสิทธิ์ผู้ใช้
หากต้องการอนุญาตให้ผู้ใช้ของคุณเข้าถึงช่องส่วนตัวบน Pusher คุณสามารถใช้ฟังก์ชัน authorizeChannel
:
$ pusher -> authorizeChannel ( ' private-my-channel ' , ' socket_id ' );
สำหรับข้อมูลเพิ่มเติม โปรดดูที่การอนุญาตผู้ใช้
การใช้ช่องทางการแสดงตนจะคล้ายกับช่องทางส่วนตัว แต่คุณสามารถระบุข้อมูลเพิ่มเติมเพื่อระบุผู้ใช้รายนั้นได้:
$ pusher -> authorizePresenceChannel ( ' presence-my-channel ' , ' socket_id ' , ' user_id ' , ' user_info ' );
สำหรับข้อมูลเพิ่มเติม โปรดดูที่การอนุญาตผู้ใช้
ไลบรารีนี้มีวิธีในการตรวจสอบว่า webhooks ที่คุณได้รับจาก Pusher เป็นเว็บฮุคของแท้จาก Pusher อีกทั้งยังมีโครงสร้างสำหรับจัดเก็บอีกด้วย วิธีการช่วยเหลือที่เรียกว่า webhook
เปิดใช้งานสิ่งนี้ ส่งส่วนหัวและเนื้อหาของคำขอ จากนั้นจะส่งออบเจ็กต์ Webhook กลับมาพร้อมกับเหตุการณ์ที่ยืนยันแล้วของคุณ หากไลบรารีไม่สามารถตรวจสอบลายเซ็นได้ จะมีข้อยกเว้นเกิดขึ้นแทน
$ webhook = $ pusher -> webhook ( $ request_headers , $ request_body );
$ number_of_events = count ( $ webhook -> get_events ());
$ time_received = $ webhook -> get_time_ms ();
ไลบรารีนี้รองรับการเข้ารหัสจากต้นทางถึงปลายทางของช่องส่วนตัวของคุณ ซึ่งหมายความว่ามีเพียงคุณและไคลเอนต์ที่เชื่อมต่อของคุณเท่านั้นที่จะสามารถอ่านข้อความของคุณได้ Pusher ไม่สามารถถอดรหัสได้ คุณสามารถเปิดใช้งานคุณสมบัตินี้ได้โดยทำตามขั้นตอนเหล่านี้:
คุณควรตั้งค่าช่องส่วนตัวก่อน สิ่งนี้เกี่ยวข้องกับการสร้างจุดสิ้นสุดการอนุญาตบนเซิร์ฟเวอร์ของคุณ
จากนั้น สร้างคีย์เข้ารหัสหลักขนาด 32 ไบต์ เข้ารหัส base64 และจัดเก็บอย่างปลอดภัย นี่เป็นความลับและคุณไม่ควรแชร์สิ่งนี้กับใครเลย ไม่แม้แต่พุชเชอร์
หากต้องการสร้างคีย์ที่เหมาะสมจากแหล่งสุ่มที่ดี คุณสามารถใช้คำสั่ง openssl
:
openssl rand -base64 32
ระบุคีย์เข้ารหัสหลักของคุณเมื่อสร้างไคลเอนต์ Pusher ของคุณ:
$ pusher = new Pusher Pusher (
$ app_key ,
$ app_secret ,
$ app_id ,
[
' cluster ' => $ app_cluster ,
' encryption_master_key_base64 ' => " <your base64 encoded master key> "
]
);
ช่องที่คุณต้องการใช้การเข้ารหัสจากต้นทางถึงปลายทางควรขึ้นต้นด้วย private-encrypted-
สมัครสมาชิกช่องเหล่านี้ในไคลเอนต์ของคุณ เท่านี้ก็เสร็จเรียบร้อย! คุณสามารถตรวจสอบว่าใช้งานได้โดยตรวจสอบคอนโซลแก้ไขข้อบกพร่องบน https://dashboard.pusher.com/ และดูข้อความเข้ารหัสที่มีสัญญาณรบกวน
หมายเหตุสำคัญ: สิ่งนี้จะไม่เข้ารหัสข้อความในช่องที่ไม่ได้ขึ้นต้นด้วย private-encrypted-
ข้อจำกัด : คุณไม่สามารถทริกเกอร์เหตุการณ์เดียวบนช่องสัญญาณที่ไม่ได้เข้ารหัสและเข้ารหัสผสมกันในการเรียกเพื่อ trigger
เช่น
$ data [ ' name ' ] = ' joe ' ;
$ data [ ' message_count ' ] = 23 ;
$ pusher -> trigger ([ ' channel-1 ' , ' private-encrypted-channel-2 ' ], ' test_event ' , $ data );
เหตุผล: วิธีการในไลบรารีนี้จะแมปโดยตรงกับคำขอ Channels HTTP API แต่ละรายการ หากเราอนุญาตให้ทริกเกอร์เหตุการณ์เดียวในหลายช่องทาง (บางรายการเข้ารหัส บางรายการไม่ได้เข้ารหัส) ก็จะต้องมีคำขอ API สองรายการ: รายการหนึ่งมีการเข้ารหัสเหตุการณ์ไปยังช่องสัญญาณที่เข้ารหัส และอีกรายการหนึ่งซึ่งเหตุการณ์ไม่ได้เข้ารหัสสำหรับช่องที่ไม่ได้เข้ารหัส
ขั้นแรกให้ตั้งค่าจุดสิ้นสุดการอนุญาตช่องในแอป JS ของคุณเมื่อสร้างวัตถุ Pusher:
var pusher = new Pusher ( "app_key" ,
// ...
channelAuthorization : {
endpoint : "/presenceAuth.php" ,
} ,
) ;
ถัดไป สร้างสิ่งต่อไปนี้ใน PresenceAuth.php:
<?php
header ( ' Content-Type: application/json ' );
if ( isset ( $ _SESSION [ ' user_id ' ])) {
$ stmt = $ pdo -> prepare ( " SELECT * FROM `users` WHERE id = :id " );
$ stmt -> bindValue ( ' :id ' , $ _SESSION [ ' user_id ' ], PDO :: PARAM_INT );
$ stmt -> execute ();
$ user = $ stmt -> fetch ();
} else {
die ( json_encode ( ' no-one is logged in ' ));
}
$ pusher = new Pusher Pusher ( $ key , $ secret , $ app_id );
$ presence_data = [ ' name ' => $ user [ ' name ' ]];
echo $ pusher -> authorizePresenceChannel ( $ _POST [ ' channel_name ' ], $ _POST [ ' socket_id ' ], $ user [ ' id ' ], $ presence_data );
หมายเหตุ: จะถือว่าคุณจัดเก็บผู้ใช้ของคุณในตารางที่เรียกว่า users
และผู้ใช้เหล่านั้นมีคอลัมน์ name
นอกจากนี้ยังถือว่าคุณมีกลไกการเข้าสู่ระบบที่เก็บ user_id
ของผู้ใช้ที่เข้าสู่ระบบในเซสชัน
$ pusher -> getChannelInfo ( $ name );
นอกจากนี้ยังสามารถรับข้อมูลเกี่ยวกับช่องจาก Channels HTTP API ได้อีกด้วย
$ info = $ pusher -> getChannelInfo ( ' channel-name ' );
$ channel_occupied = $ info -> occupied ;
สำหรับช่องการแสดงตน คุณยังสามารถสอบถามจำนวนผู้ใช้ที่แตกต่างกันซึ่งปัจจุบันสมัครรับข้อมูลจากช่องนี้ (ผู้ใช้รายเดียวอาจสมัครรับข้อมูลหลายครั้ง แต่จะนับเป็นหนึ่งเดียวเท่านั้น):
$ info = $ pusher -> getChannelInfo ( ' presence-channel-name ' , [ ' info ' => ' user_count ' ]);
$ user_count = $ info -> user_count ;
หากคุณเปิดใช้งานความสามารถในการสืบค้น subscription_count
(จำนวนการเชื่อมต่อที่สมัครเป็นสมาชิกช่องนี้ในปัจจุบัน) คุณสามารถสืบค้นค่านี้ได้ดังนี้:
$ info = $ pusher -> getChannelInfo ( ' presence-channel-name ' , [ ' info ' => ' subscription_count ' ]);
$ subscription_count = $ info -> subscription_count ;
$ pusher -> getChannels ();
นอกจากนี้ยังสามารถรับรายการช่องสำหรับแอปพลิเคชันจาก Channels HTTP API ได้อีกด้วย
$ result = $ pusher -> getChannels ();
$ channel_count = count ( $ result -> channels ); // $channels is an Array
$ pusher -> getChannels ([ ' filter_by_prefix ' => ' some_filter ' ]);
นอกจากนี้ยังสามารถรับรายชื่อช่องตามคำนำหน้าชื่อได้อีกด้วย ในการดำเนินการนี้ คุณจะต้องระบุพารามิเตอร์ $options
ให้กับการโทร ในตัวอย่างต่อไปนี้ การโทรจะส่งคืนรายการช่องทั้งหมดที่มีคำนำหน้า presence-
นี่เป็นแนวคิดในการดึงรายการช่องทางการแสดงตนทั้งหมด
$ results = $ pusher -> getChannels ([ ' filter_by_prefix ' => ' presence- ' ]);
$ channel_count = count ( $ result -> channels ); // $channels is an Array
สิ่งนี้สามารถทำได้โดยใช้ฟังก์ชัน pusher->get
ทั่วไป:
$ pusher -> get ( ' /channels ' , [ ' filter_by_prefix ' => ' presence- ' ]);
HTTP API ที่ส่งคืนรายการช่องไม่รองรับการส่งคืนจำนวนการสมัครรับข้อมูลพร้อมกับแต่ละช่อง แต่คุณสามารถดึงข้อมูลนี้ได้โดยวนซ้ำแต่ละช่องทางและทำการร้องขออีกครั้ง ได้รับการเตือน: วิธีการนี้ใช้ข้อความ (จำนวนช่อง + 1)!
<?php
$ subscription_counts = [];
foreach ( $ pusher -> getChannels ()-> channels as $ channel => $ v ) {
$ subscription_counts [ $ channel ] =
$ pusher -> getChannelInfo (
$ channel , [ ' info ' => ' subscription_count ' ]
)-> subscription_count ;
}
var_dump ( $ subscription_counts );
$ results = $ pusher -> getPresenceUsers ( ' presence-channel-name ' );
$ users_count = count ( $ results -> users ); // $users is an Array
สิ่งนี้สามารถทำได้โดยใช้ฟังก์ชัน pusher->get
ทั่วไป:
$ response = $ pusher -> get ( ' /channels/presence-channel-name/users ' );
$response
อยู่ในรูปแบบ:
Array (
[body] => { " users " :[{ " id " :"a_user_id"}]}
[status] => 200
[result] => Array (
[users] => Array (
[ 0 ] => Array (
[id] => a_user_id
),
/* Additional users */
)
)
)
$ pusher -> get ( $ path , $ params );
ใช้เพื่อสร้างแบบสอบถาม GET
กับ Channels HTTP API จัดการการรับรองความถูกต้อง
การตอบสนองเป็นอาเรย์แบบเชื่อมโยงที่มีดัชนี result
เนื้อหาของดัชนีนี้ขึ้นอยู่กับวิธี HTTP ที่ถูกเรียก อย่างไรก็ตาม คุณสมบัติ status
ที่อนุญาตรหัสสถานะ HTTP จะแสดงอยู่เสมอ และคุณสมบัติ result
จะถูกตั้งค่าหากรหัสสถานะบ่งชี้ว่าการเรียก API สำเร็จ
$ response = $ pusher -> get ( ' /channels ' );
$ http_status_code = $ response [ ' status ' ];
$ result = $ response [ ' result ' ];
ต้องใช้ phpunit
composer install
tests
config.example.php
เป็น config.php
และแทนที่ค่าด้วยข้อมูลประจำตัว Channels ที่ถูกต้อง หรือ สร้างตัวแปรสภาพแวดล้อมcomposer exec phpunit
เพื่อรันการทดสอบทั้งหมด ลิขสิทธิ์ 2014 พุชเชอร์ ได้รับอนุญาตภายใต้ใบอนุญาต MIT: https://www.opensource.org/licenses/mit-license.php
ลิขสิทธิ์ 2010, Squeeks ได้รับอนุญาตภายใต้ใบอนุญาต MIT: https://www.opensource.org/licenses/mit-license.php