Async การสตรีมข้อความธรรมดา TCP/IP และเซิร์ฟเวอร์ซ็อกเก็ต TLS ที่ปลอดภัยและการเชื่อมต่อไคลเอนต์สำหรับ ReactPHP
เวอร์ชันการพัฒนา: สาขานี้มีโค้ดสำหรับเวอร์ชัน v3 ที่กำลังจะมาถึง สำหรับโค้ดของเวอร์ชัน v1 ที่เสถียรในปัจจุบัน โปรดดูที่สาขา
1.x
การเปิดตัว v3 ที่กำลังจะมาถึงจะเป็นหนทางข้างหน้าสำหรับแพ็คเกจนี้ อย่างไรก็ตาม เราจะยังคงสนับสนุนเวอร์ชัน 1 สำหรับผู้ที่ยังไม่ได้เป็นเวอร์ชันล่าสุด ดูคำแนะนำในการติดตั้งสำหรับรายละเอียดเพิ่มเติม
ไลบรารีซ็อกเก็ตจัดเตรียมอินเทอร์เฟซที่นำมาใช้ซ้ำได้สำหรับเซิร์ฟเวอร์และไคลเอนต์ชั้นซ็อกเก็ตตามส่วนประกอบ EventLoop
และ Stream
ส่วนประกอบเซิร์ฟเวอร์ช่วยให้คุณสร้างเซิร์ฟเวอร์เครือข่ายที่ยอมรับการเชื่อมต่อขาเข้าจากไคลเอนต์เครือข่าย (เช่นเซิร์ฟเวอร์ HTTP) ส่วนประกอบไคลเอนต์ช่วยให้คุณสร้างไคลเอนต์เครือข่ายที่สร้างการเชื่อมต่อขาออกไปยังเซิร์ฟเวอร์เครือข่าย (เช่น HTTP หรือไคลเอนต์ฐานข้อมูล) ไลบรารีนี้มีวิธีสตรีมมิ่งแบบอะซิงก์สำหรับทั้งหมดนี้ ดังนั้นคุณจึงสามารถจัดการการเชื่อมต่อหลายรายการพร้อมกันโดยไม่ปิดกั้น
สารบัญ
นี่คือเซิร์ฟเวอร์ที่จะปิดการเชื่อมต่อหากคุณส่งสิ่งใดไป:
$ socket = new React Socket SocketServer ( ' 127.0.0.1:8080 ' );
$ socket -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( " Hello " . $ connection -> getRemoteAddress () . " ! n" );
$ connection -> write ( " Welcome to this amazing server! n" );
$ connection -> write ( " Here's a tip: don't say anything. n" );
$ connection -> on ( ' data ' , function ( $ data ) use ( $ connection ) {
$ connection -> close ();
});
});
ดูตัวอย่างด้วย
นี่คือไคลเอนต์ที่ส่งออกผลลัพธ์ของเซิร์ฟเวอร์ดังกล่าวแล้วพยายามส่งสตริง:
$ connector = new React Socket Connector ();
$ connector -> connect ( ' 127.0.0.1:8080 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> pipe ( new React Stream WritableResourceStream ( STDOUT ));
$ connection -> write ( " Hello World! n" );
}, function ( Exception $ e ) {
echo ' Error: ' . $ e -> getMessage () . PHP_EOL ;
});
ConnectionInterface
ใช้เพื่อแสดงการเชื่อมต่อขาเข้าและขาออก เช่น การเชื่อมต่อ TCP/IP ปกติ
การเชื่อมต่อขาเข้าหรือขาออกคือสตรีมดูเพล็กซ์ (ทั้งอ่านและเขียนได้) ที่ใช้ DuplexStreamInterface
ของ React มีคุณสมบัติเพิ่มเติมสำหรับที่อยู่ในเครื่องและที่อยู่ระยะไกล (IP ไคลเอ็นต์) ซึ่งมีการสร้างการเชื่อมต่อนี้ไปยัง/จาก
โดยทั่วไปแล้ว อินสแตนซ์ที่ใช้ ConnectionInterface
นี้จะถูกปล่อยออกมาจากคลาสทั้งหมดที่ใช้ ServerInterface
และใช้โดยคลาสทั้งหมดที่ใช้ ConnectorInterface
เนื่องจาก ConnectionInterface
ใช้ DuplexStreamInterface
พื้นฐาน คุณจึงสามารถใช้เหตุการณ์และวิธีการต่างๆ ได้ตามปกติ:
$ connection -> on ( ' data ' , function ( $ chunk ) {
echo $ chunk ;
});
$ connection -> on ( ' end ' , function () {
echo ' ended ' ;
});
$ connection -> on ( ' error ' , function ( Exception $ e ) {
echo ' error: ' . $ e -> getMessage ();
});
$ connection -> on ( ' close ' , function () {
echo ' closed ' ;
});
$ connection -> write ( $ data );
$ connection -> end ( $ data = null );
$ connection -> close ();
// …
สำหรับรายละเอียดเพิ่มเติม โปรดดูที่ DuplexStreamInterface
getRemoteAddress(): ?string
วิธีการส่งคืนที่อยู่ระยะไกลแบบเต็ม (URI) ที่ใช้สร้างการเชื่อมต่อนี้
$ address = $ connection -> getRemoteAddress ();
echo ' Connection with ' . $ address . PHP_EOL ;
หากไม่สามารถระบุที่อยู่ระยะไกลหรือไม่ทราบได้ในขณะนี้ (เช่นหลังจากปิดการเชื่อมต่อแล้ว) อาจส่งคืนค่า NULL
แทน
มิฉะนั้น จะส่งคืนที่อยู่แบบเต็ม (URI) เป็นค่าสตริง เช่น tcp://127.0.0.1:8080
, tcp://[::1]:80
, tls://127.0.0.1:443
, unix://example.sock
หรือ unix:///path/to/example.sock
โปรดทราบว่าส่วนประกอบ URI แต่ละรายการเป็นแอปพลิเคชันเฉพาะและขึ้นอยู่กับโปรโตคอลการขนส่งที่เกี่ยวข้อง
หากนี่คือการเชื่อมต่อที่ใช้ TCP/IP และคุณต้องการเฉพาะ IP ระยะไกล คุณอาจใช้สิ่งนี้:
$ address = $ connection -> getRemoteAddress ();
$ ip = trim ( parse_url ( $ address , PHP_URL_HOST ), ' [] ' );
echo ' Connection with ' . $ ip . PHP_EOL ;
getLocalAddress(): ?string
วิธีการส่งคืนที่อยู่แบบเต็ม (URI) ที่ใช้สร้างการเชื่อมต่อนี้
$ address = $ connection -> getLocalAddress ();
echo ' Connection with ' . $ address . PHP_EOL ;
หากไม่สามารถระบุที่อยู่ในเครื่องได้หรือไม่ทราบในขณะนี้ (เช่น หลังจากปิดการเชื่อมต่อแล้ว) อาจส่งคืนค่า NULL
แทน
มิฉะนั้น จะส่งคืนที่อยู่แบบเต็ม (URI) เป็นค่าสตริง เช่น tcp://127.0.0.1:8080
, tcp://[::1]:80
, tls://127.0.0.1:443
, unix://example.sock
หรือ unix:///path/to/example.sock
โปรดทราบว่าส่วนประกอบ URI แต่ละรายการเป็นแอปพลิเคชันเฉพาะและขึ้นอยู่กับโปรโตคอลการขนส่งที่เกี่ยวข้อง
เมธอดนี้เป็นส่วนเสริมเมธอด getRemoteAddress()
ดังนั้นจึงไม่ควรสับสน
หากอินสแตนซ์ TcpServer
ของคุณกำลังรับฟังบนหลายอินเทอร์เฟซ (เช่น การใช้ที่อยู่ 0.0.0.0
) คุณสามารถใช้วิธีนี้เพื่อค้นหาว่าอินเทอร์เฟซใดที่ยอมรับการเชื่อมต่อนี้จริง ๆ (เช่น อินเทอร์เฟซสาธารณะหรือภายในเครื่อง)
หากระบบของคุณมีหลายอินเทอร์เฟซ (เช่น อินเทอร์เฟซ WAN และ LAN) คุณสามารถใช้วิธีนี้เพื่อดูว่าจริงๆ แล้วใช้อินเทอร์เฟซใดสำหรับการเชื่อมต่อนี้
ServerInterface
มีหน้าที่รับผิดชอบในการจัดหาอินเทอร์เฟซสำหรับยอมรับการเชื่อมต่อสตรีมมิ่งขาเข้า เช่น การเชื่อมต่อ TCP/IP ปกติ
ส่วนประกอบระดับสูงกว่าส่วนใหญ่ (เช่น เซิร์ฟเวอร์ HTTP) ยอมรับอินสแตนซ์ที่ใช้อินเทอร์เฟซนี้เพื่อยอมรับการเชื่อมต่อสตรีมมิ่งขาเข้า โดยปกติจะทำผ่านการฉีดการขึ้นต่อกัน ดังนั้นจึงค่อนข้างง่ายที่จะสลับการใช้งานนี้กับการใช้งานอื่น ๆ ของอินเทอร์เฟซนี้ ซึ่งหมายความว่าคุณควรพิมพ์คำใบ้ต่ออินเทอร์เฟซนี้ แทนที่จะใช้อินเทอร์เฟซนี้อย่างเป็นรูปธรรม
นอกเหนือจากการกำหนดวิธีการบางอย่างแล้ว อินเทอร์เฟซนี้ยังใช้ EventEmitterInterface
ซึ่งช่วยให้คุณสามารถตอบสนองต่อเหตุการณ์บางอย่างได้
เหตุการณ์ connection
จะถูกส่งออกมาทุกครั้งที่มีการสร้างการเชื่อมต่อใหม่ เช่น ไคลเอนต์ใหม่เชื่อมต่อกับซ็อกเก็ตเซิร์ฟเวอร์นี้:
$ socket -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' new connection ' . PHP_EOL ;
});
ดูเพิ่มเติมที่ ConnectionInterface
สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการจัดการการเชื่อมต่อขาเข้า
เหตุการณ์ error
จะถูกส่งออกมาทุกครั้งที่มีข้อผิดพลาดในการยอมรับการเชื่อมต่อใหม่จากไคลเอนต์
$ socket -> on ( ' error ' , function ( Exception $ e ) {
echo ' error: ' . $ e -> getMessage () . PHP_EOL ;
});
โปรดทราบว่านี่ไม่ใช่เหตุการณ์ข้อผิดพลาดร้ายแรง กล่าวคือ เซิร์ฟเวอร์คอยรับฟังการเชื่อมต่อใหม่แม้หลังจากเหตุการณ์นี้แล้ว
getAddress(): ?string
วิธีการสามารถใช้เพื่อส่งคืนที่อยู่แบบเต็ม (URI) ที่เซิร์ฟเวอร์นี้กำลังรับฟังอยู่
$ address = $ socket -> getAddress ();
echo ' Server listening on ' . $ address . PHP_EOL ;
หากไม่สามารถระบุที่อยู่ได้หรือไม่ทราบในขณะนี้ (เช่นหลังจากปิดซ็อกเก็ตแล้ว) อาจส่งกลับค่า NULL
แทน
มิฉะนั้น จะส่งคืนที่อยู่แบบเต็ม (URI) เป็นค่าสตริง เช่น tcp://127.0.0.1:8080
, tcp://[::1]:80
, tls://127.0.0.1:443
unix://example.sock
หรือ unix:///path/to/example.sock
โปรดทราบว่าส่วนประกอบ URI แต่ละรายการเป็นแอปพลิเคชันเฉพาะและขึ้นอยู่กับโปรโตคอลการขนส่งที่เกี่ยวข้อง
หากนี่คือเซิร์ฟเวอร์ที่ใช้ TCP/IP และคุณต้องการเฉพาะพอร์ตภายในเครื่อง คุณอาจใช้สิ่งนี้:
$ address = $ socket -> getAddress ();
$ port = parse_url ( $ address , PHP_URL_PORT );
echo ' Server listening on port ' . $ port . PHP_EOL ;
pause(): void
สามารถใช้เพื่อหยุดการยอมรับการเชื่อมต่อขาเข้าใหม่ชั่วคราว
ลบทรัพยากรซ็อกเก็ตออกจาก EventLoop และหยุดการยอมรับการเชื่อมต่อใหม่ โปรดทราบว่าซ็อกเก็ตการฟังยังคงทำงานอยู่และไม่ได้ปิด
ซึ่งหมายความว่าการเชื่อมต่อขาเข้าใหม่จะยังคงค้างอยู่ใน Backlog ของระบบปฏิบัติการจนกว่า Backlog ที่กำหนดค่าได้จะเต็ม เมื่อ Backlog เต็มแล้ว ระบบปฏิบัติการอาจปฏิเสธการเชื่อมต่อขาเข้าเพิ่มเติมจนกว่า Backlog จะถูกระบายออกอีกครั้งโดยดำเนินการต่อเพื่อยอมรับการเชื่อมต่อใหม่
เมื่อเซิร์ฟเวอร์ถูกหยุดชั่วคราว ไม่ควรส่งเหตุการณ์ connection
เพิ่มเติมอีก
$ socket -> pause ();
$ socket -> on ( ' connection ' , assertShouldNeverCalled ());
วิธีการนี้เป็นคำแนะนำเท่านั้น แม้ว่าโดยทั่วไปจะไม่แนะนำ แต่เซิร์ฟเวอร์อาจยังคงส่งเหตุการณ์ connection
ต่อต่อไป
เว้นแต่จะระบุไว้เป็นอย่างอื่น เซิร์ฟเวอร์ที่เปิดสำเร็จไม่ควรเริ่มทำงานในสถานะหยุดชั่วคราว
คุณสามารถประมวลผลเหตุการณ์ต่อได้โดยการเรียก resume()
อีกครั้ง
โปรดทราบว่าทั้งสองวิธีสามารถเรียกได้กี่ครั้งก็ได้ โดยเฉพาะอย่างยิ่งการเรียก pause()
มากกว่าหนึ่งครั้งไม่ควรมีผลใดๆ ในทำนองเดียวกัน การเรียกสิ่งนี้หลังจาก close()
ถือเป็น NO-OP
สามารถใช้เมธอด resume(): void
เพื่อดำเนินการรับการเชื่อมต่อขาเข้าใหม่ต่อได้
แนบทรัพยากรซ็อกเก็ตเข้ากับ EventLoop อีกครั้งหลังจาก pause()
ก่อนหน้า
$ socket -> pause ();
Loop:: addTimer ( 1.0 , function () use ( $ socket ) {
$ socket -> resume ();
});
โปรดทราบว่าทั้งสองวิธีสามารถเรียกได้กี่ครั้งก็ได้ โดยเฉพาะอย่างยิ่งการเรียก resume()
โดยไม่มี pause()
ก่อนหน้าไม่ควรมีผลใดๆ ในทำนองเดียวกัน การเรียกสิ่งนี้หลังจาก close()
ถือเป็น NO-OP
เมธอด close(): void
สามารถใช้เพื่อปิดซ็อกเก็ตการฟังนี้
การดำเนินการนี้จะหยุดฟังการเชื่อมต่อขาเข้าใหม่บนซ็อกเก็ตนี้
echo ' Shutting down server socket ' . PHP_EOL ;
$ socket -> close ();
การเรียกเมธอดนี้มากกว่าหนึ่งครั้งในอินสแตนซ์เดียวกันถือเป็น NO-OP
คลาส SocketServer
เป็นคลาสหลักในแพ็คเกจนี้ที่ใช้ ServerInterface
และอนุญาตให้คุณยอมรับการเชื่อมต่อสตรีมมิ่งขาเข้า เช่น TCP/IP แบบข้อความธรรมดาหรือสตรีมการเชื่อมต่อ TLS ที่ปลอดภัย
เพื่อที่จะยอมรับการเชื่อมต่อ TCP/IP แบบข้อความธรรมดา คุณสามารถส่งผ่านโฮสต์และพอร์ตรวมกันได้ดังนี้:
$ socket = new React Socket SocketServer ( ' 127.0.0.1:8080 ' );
การฟังที่อยู่ localhost 127.0.0.1
หมายความว่าจะไม่สามารถเข้าถึงได้จากภายนอกระบบนี้ ในการเปลี่ยนโฮสต์ที่ซ็อกเก็ตกำลังรับฟัง คุณสามารถระบุที่อยู่ IP ของอินเทอร์เฟซ หรือใช้ที่อยู่พิเศษ 0.0.0.0
เพื่อฟังบนอินเทอร์เฟซทั้งหมด:
$ socket = new React Socket SocketServer ( ' 0.0.0.0:8080 ' );
หากคุณต้องการฟังบนที่อยู่ IPv6 คุณต้องใส่โฮสต์ไว้ในวงเล็บเหลี่ยม:
$ socket = new React Socket SocketServer ( ' [::1]:8080 ' );
หากต้องการใช้การกำหนดพอร์ตแบบสุ่ม คุณสามารถใช้พอร์ต 0
:
$ socket = new React Socket SocketServer ( ' 127.0.0.1:0 ' );
$ address = $ socket -> getAddress ();
หากต้องการฟังบนเส้นทางซ็อกเก็ตโดเมน Unix (UDS) คุณต้องใส่คำนำหน้า URI ด้วยรูปแบบ unix://
:
$ socket = new React Socket SocketServer ( ' unix:///tmp/server.sock ' );
หากต้องการฟังหมายเลข file descriptor (FD) ที่มีอยู่ คุณต้องใส่ URI นำหน้าด้วย php://fd/
ดังนี้:
$ socket = new React Socket SocketServer ( ' php://fd/3 ' );
หาก URI ที่กำหนดไม่ถูกต้อง ไม่มีพอร์ต ไม่มีรูปแบบอื่นใด หรือหากมีชื่อโฮสต์ ก็จะส่ง InvalidArgumentException
:
// throws InvalidArgumentException due to missing port
$ socket = new React Socket SocketServer ( ' 127.0.0.1 ' );
หาก URI ที่กำหนดดูเหมือนว่าถูกต้อง แต่การฟังนั้นล้มเหลว (เช่น หากพอร์ตมีการใช้งานอยู่แล้ว หรือพอร์ตที่ต่ำกว่า 1,024 อาจต้องมีการเข้าถึงรูท เป็นต้น) มันจะส่ง RuntimeException
:
$ first = new React Socket SocketServer ( ' 127.0.0.1:8080 ' );
// throws RuntimeException because port is already in use
$ second = new React Socket SocketServer ( ' 127.0.0.1:8080 ' );
โปรดทราบว่าเงื่อนไขข้อผิดพลาดเหล่านี้อาจแตกต่างกันไปขึ้นอยู่กับระบบและ/หรือการกำหนดค่าของคุณ ดูข้อความข้อยกเว้นและรหัสสำหรับรายละเอียดเพิ่มเติมเกี่ยวกับเงื่อนไขข้อผิดพลาดจริง
หรือคุณสามารถระบุตัวเลือกบริบทซ็อกเก็ต TCP สำหรับทรัพยากรซ็อกเก็ตกระแสข้อมูลพื้นฐานดังนี้:
$ socket = new React Socket SocketServer ( ' [::1]:8080 ' , [
' tcp ' => [
' backlog ' => 200 ,
' so_reuseport ' => true ,
' ipv6_v6only ' => true
]
]);
โปรดทราบว่าตัวเลือกบริบทของซ็อกเก็ตที่มีอยู่ ค่าเริ่มต้นและผลกระทบของการเปลี่ยนแปลงเหล่านี้อาจแตกต่างกันไปขึ้นอยู่กับระบบและ/หรือเวอร์ชัน PHP ของคุณ การส่งผ่านตัวเลือกบริบทที่ไม่รู้จักจะไม่มีผลใดๆ ตัวเลือกบริบท
backlog
มีค่าเริ่มต้นเป็น511
เว้นแต่จะได้รับอย่างชัดเจน
คุณสามารถเริ่มต้นเซิร์ฟเวอร์ TLS ที่ปลอดภัย (เดิมเรียกว่า SSL) ได้โดยเพียงแค่เพิ่มโครงร่าง tls://
URI ไว้หน้า ภายในจะรอการเชื่อมต่อ TCP/IP แบบข้อความธรรมดา จากนั้นจึงดำเนินการจับมือ TLS สำหรับการเชื่อมต่อแต่ละรายการ ดังนั้นจึงต้องใช้ตัวเลือกบริบท TLS ที่ถูกต้อง ซึ่งในรูปแบบพื้นฐานที่สุดอาจมีลักษณะเช่นนี้หากคุณใช้ไฟล์ใบรับรองที่เข้ารหัส PEM:
$ socket = new React Socket SocketServer ( ' tls://127.0.0.1:8080 ' , [
' tls ' => [
' local_cert ' => ' server.pem '
]
]);
โปรดทราบว่าไฟล์ใบรับรองจะไม่ถูกโหลดในอินสแตนซ์ แต่เมื่อการเชื่อมต่อขาเข้าเริ่มต้นบริบท TLS นี่หมายความว่าเส้นทางไฟล์ใบรับรองหรือเนื้อหาที่ไม่ถูกต้องจะทำให้เกิดเหตุการณ์
error
ในภายหลังเท่านั้น
หากคีย์ส่วนตัวของคุณถูกเข้ารหัสด้วยข้อความรหัสผ่าน คุณต้องระบุดังนี้:
$ socket = new React Socket SocketServer ( ' tls://127.0.0.1:8000 ' , [
' tls ' => [
' local_cert ' => ' server.pem ' ,
' passphrase ' => ' secret '
]
]);
ตามค่าเริ่มต้น เซิร์ฟเวอร์นี้รองรับ TLSv1.0+ และไม่รวมการรองรับ SSLv2/SSLv3 รุ่นเก่า คุณยังสามารถเลือกเวอร์ชัน TLS ที่คุณต้องการเจรจากับฝ่ายระยะไกลได้อย่างชัดเจน:
$ socket = new React Socket SocketServer ( ' tls://127.0.0.1:8000 ' , [
' tls ' => [
' local_cert ' => ' server.pem ' ,
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
]
]);
โปรดทราบว่าตัวเลือกบริบท TLS ที่มี ค่าเริ่มต้นและผลกระทบของการเปลี่ยนแปลงอาจแตกต่างกันไปขึ้นอยู่กับระบบและ/หรือเวอร์ชัน PHP ของคุณ อาร์เรย์บริบทภายนอกช่วยให้คุณสามารถใช้ตัวเลือกบริบท
tcp
(และอาจมีมากกว่านั้น) ได้ในเวลาเดียวกัน การส่งผ่านตัวเลือกบริบทที่ไม่รู้จักจะไม่มีผลใดๆ หากคุณไม่ได้ใช้รูปแบบtls://
การส่งตัวเลือกบริบทtls
จะไม่มีผลใดๆ
เมื่อใดก็ตามที่ไคลเอนต์เชื่อมต่อ มันจะปล่อยเหตุการณ์ connection
กับอินสแตนซ์การเชื่อมต่อที่ใช้ ConnectionInterface
:
$ socket -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' Plaintext connection from ' . $ connection -> getRemoteAddress () . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
ดูเพิ่มเติมที่ ServerInterface
สำหรับรายละเอียดเพิ่มเติม
คลาสนี้รับพารามิเตอร์ทางเลือก LoopInterface|null $loop
ที่สามารถใช้เพื่อส่งผ่านอินสแตนซ์ลูปเหตุการณ์เพื่อใช้สำหรับอ็อบเจ็กต์นี้ คุณสามารถใช้ค่า null
ที่นี่เพื่อใช้การวนซ้ำเริ่มต้น ไม่ควรระบุค่านี้ เว้นแต่คุณแน่ใจว่าต้องการใช้อินสแตนซ์ลูปเหตุการณ์ที่กำหนดอย่างชัดเจน
โปรดทราบว่าคลาส
SocketServer
เป็นการใช้งานที่เป็นรูปธรรมสำหรับซ็อกเก็ต TCP/IP หากคุณต้องการพิมพ์คำแนะนำในการใช้งานโปรโตคอลระดับสูงกว่า คุณควรใช้ServerInterface
ทั่วไปแทน
คลาส TcpServer
ใช้ ServerInterface
และรับผิดชอบในการยอมรับการเชื่อมต่อ TCP/IP แบบข้อความธรรมดา
$ server = new React Socket TcpServer ( 8080 );
ตามที่กล่าวไว้ข้างต้น พารามิเตอร์ $uri
สามารถประกอบด้วยได้เพียงพอร์ตเดียว ซึ่งในกรณีนี้เซิร์ฟเวอร์จะใช้ค่าเริ่มต้นในการฟังบนที่อยู่ localhost 127.0.0.1
ซึ่งหมายความว่าจะไม่สามารถเข้าถึงได้จากภายนอกระบบนี้
หากต้องการใช้การกำหนดพอร์ตแบบสุ่ม คุณสามารถใช้พอร์ต 0
:
$ server = new React Socket TcpServer ( 0 );
$ address = $ server -> getAddress ();
ในการเปลี่ยนโฮสต์ที่ซ็อกเก็ตกำลังรับฟัง คุณสามารถระบุที่อยู่ IP ผ่านพารามิเตอร์แรกที่มอบให้กับตัวสร้าง ซึ่งเป็นทางเลือกที่นำหน้าด้วยโครงร่าง tcp://
:
$ server = new React Socket TcpServer ( ' 192.168.0.1:8080 ' );
หากคุณต้องการฟังบนที่อยู่ IPv6 คุณต้องใส่โฮสต์ไว้ในวงเล็บเหลี่ยม:
$ server = new React Socket TcpServer ( ' [::1]:8080 ' );
หาก URI ที่กำหนดไม่ถูกต้อง ไม่มีพอร์ต ไม่มีรูปแบบอื่นใด หรือหากมีชื่อโฮสต์ ก็จะส่ง InvalidArgumentException
:
// throws InvalidArgumentException due to missing port
$ server = new React Socket TcpServer ( ' 127.0.0.1 ' );
หาก URI ที่กำหนดดูเหมือนว่าถูกต้อง แต่การฟังนั้นล้มเหลว (เช่น หากพอร์ตมีการใช้งานอยู่แล้ว หรือพอร์ตที่ต่ำกว่า 1,024 อาจต้องมีการเข้าถึงรูท เป็นต้น) มันจะส่ง RuntimeException
:
$ first = new React Socket TcpServer ( 8080 );
// throws RuntimeException because port is already in use
$ second = new React Socket TcpServer ( 8080 );
โปรดทราบว่าเงื่อนไขข้อผิดพลาดเหล่านี้อาจแตกต่างกันไปขึ้นอยู่กับระบบและ/หรือการกำหนดค่าของคุณ ดูข้อความข้อยกเว้นและรหัสสำหรับรายละเอียดเพิ่มเติมเกี่ยวกับเงื่อนไขข้อผิดพลาดจริง
คลาสนี้รับพารามิเตอร์ทางเลือก LoopInterface|null $loop
ที่สามารถใช้เพื่อส่งผ่านอินสแตนซ์ลูปเหตุการณ์เพื่อใช้สำหรับอ็อบเจ็กต์นี้ คุณสามารถใช้ค่า null
ที่นี่เพื่อใช้การวนซ้ำเริ่มต้น ไม่ควรระบุค่านี้ เว้นแต่คุณแน่ใจว่าต้องการใช้อินสแตนซ์ลูปเหตุการณ์ที่กำหนดอย่างชัดเจน
ทางเลือก คุณสามารถระบุตัวเลือกบริบทของซ็อกเก็ตสำหรับทรัพยากรซ็อกเก็ตกระแสข้อมูลพื้นฐานดังนี้:
$ server = new React Socket TcpServer ( ' [::1]:8080 ' , null , [
' backlog ' => 200 ,
' so_reuseport ' => true ,
' ipv6_v6only ' => true
]);
โปรดทราบว่าตัวเลือกบริบทของซ็อกเก็ตที่มีอยู่ ค่าเริ่มต้นและผลกระทบของการเปลี่ยนแปลงเหล่านี้อาจแตกต่างกันไปขึ้นอยู่กับระบบและ/หรือเวอร์ชัน PHP ของคุณ การส่งผ่านตัวเลือกบริบทที่ไม่รู้จักจะไม่มีผลใดๆ ตัวเลือกบริบท
backlog
มีค่าเริ่มต้นเป็น511
เว้นแต่จะได้รับอย่างชัดเจน
เมื่อใดก็ตามที่ไคลเอนต์เชื่อมต่อ มันจะปล่อยเหตุการณ์ connection
กับอินสแตนซ์การเชื่อมต่อที่ใช้ ConnectionInterface
:
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' Plaintext connection from ' . $ connection -> getRemoteAddress () . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
ดูเพิ่มเติมที่ ServerInterface
สำหรับรายละเอียดเพิ่มเติม
คลาส SecureServer
ใช้ ServerInterface
และรับผิดชอบในการจัดหาเซิร์ฟเวอร์ TLS ที่ปลอดภัย (เดิมเรียกว่า SSL)
ทำได้โดยการรวมอินสแตนซ์ TcpServer
ซึ่งจะรอการเชื่อมต่อ TCP/IP แบบข้อความธรรมดา จากนั้นจึงทำการจับมือ TLS สำหรับแต่ละการเชื่อมต่อ ดังนั้นจึงต้องใช้ตัวเลือกบริบท TLS ที่ถูกต้อง ซึ่งในรูปแบบพื้นฐานที่สุดอาจมีลักษณะเช่นนี้หากคุณใช้ไฟล์ใบรับรองที่เข้ารหัส PEM:
$ server = new React Socket TcpServer ( 8000 );
$ server = new React Socket SecureServer ( $ server , null , [
' local_cert ' => ' server.pem '
]);
โปรดทราบว่าไฟล์ใบรับรองจะไม่ถูกโหลดในอินสแตนซ์ แต่เมื่อการเชื่อมต่อขาเข้าเริ่มต้นบริบท TLS นี่หมายความว่าเส้นทางไฟล์ใบรับรองหรือเนื้อหาที่ไม่ถูกต้องจะทำให้เกิดเหตุการณ์
error
ในภายหลังเท่านั้น
หากคีย์ส่วนตัวของคุณถูกเข้ารหัสด้วยข้อความรหัสผ่าน คุณต้องระบุดังนี้:
$ server = new React Socket TcpServer ( 8000 );
$ server = new React Socket SecureServer ( $ server , null , [
' local_cert ' => ' server.pem ' ,
' passphrase ' => ' secret '
]);
ตามค่าเริ่มต้น เซิร์ฟเวอร์นี้รองรับ TLSv1.0+ และไม่รวมการรองรับ SSLv2/SSLv3 รุ่นเก่า คุณยังสามารถเลือกเวอร์ชัน TLS ที่คุณต้องการเจรจากับฝ่ายระยะไกลได้อย่างชัดเจน:
$ server = new React Socket TcpServer ( 8000 );
$ server = new React Socket SecureServer ( $ server , null , [
' local_cert ' => ' server.pem ' ,
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
]);
โปรดทราบว่าตัวเลือกบริบท TLS ที่มี ค่าเริ่มต้นและผลกระทบของการเปลี่ยนแปลงอาจแตกต่างกันไปขึ้นอยู่กับระบบและ/หรือเวอร์ชัน PHP ของคุณ การส่งผ่านตัวเลือกบริบทที่ไม่รู้จักจะไม่มีผลใดๆ
เมื่อใดก็ตามที่ไคลเอนต์แฮนด์เชค TLS เสร็จสิ้น ไคลเอนต์จะปล่อยเหตุการณ์ connection
กับอินสแตนซ์การเชื่อมต่อที่ใช้ ConnectionInterface
:
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' Secure connection from ' . $ connection -> getRemoteAddress () . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
เมื่อใดก็ตามที่ไคลเอนต์ไม่สามารถดำเนินการจับมือ TLS ได้สำเร็จ ไคลเอนต์จะปล่อยเหตุการณ์ error
จากนั้นปิดการเชื่อมต่อ TCP/IP พื้นฐาน:
$ server -> on ( ' error ' , function ( Exception $ e ) {
echo ' Error ' . $ e -> getMessage () . PHP_EOL ;
});
ดูเพิ่มเติมที่ ServerInterface
สำหรับรายละเอียดเพิ่มเติม
โปรดทราบว่าคลาส SecureServer
เป็นการใช้งานที่เป็นรูปธรรมสำหรับซ็อกเก็ต TLS หากคุณต้องการพิมพ์คำแนะนำในการใช้งานโปรโตคอลระดับสูงกว่า คุณควรใช้ ServerInterface
ทั่วไปแทน
คลาสนี้รับพารามิเตอร์ทางเลือก LoopInterface|null $loop
ที่สามารถใช้เพื่อส่งผ่านอินสแตนซ์ลูปเหตุการณ์เพื่อใช้สำหรับอ็อบเจ็กต์นี้ คุณสามารถใช้ค่า null
ที่นี่เพื่อใช้การวนซ้ำเริ่มต้น ไม่ควรระบุค่านี้ เว้นแต่คุณแน่ใจว่าต้องการใช้อินสแตนซ์ลูปเหตุการณ์ที่กำหนดอย่างชัดเจน
การใช้งานขั้นสูง: แม้จะอนุญาตให้
ServerInterface
เป็นพารามิเตอร์แรก แต่คุณควรส่งอินสแตนซ์TcpServer
เป็นพารามิเตอร์แรก เว้นแต่คุณจะรู้ว่าคุณกำลังทำอะไรอยู่ ภายในSecureServer
จะต้องตั้งค่าตัวเลือกบริบท TLS ที่จำเป็นบนทรัพยากรสตรีมที่สำคัญ ทรัพยากรเหล่านี้ไม่ได้ถูกเปิดเผยผ่านอินเทอร์เฟซใดๆ ที่กำหนดไว้ในแพ็คเกจนี้ แต่จะเปิดเผยผ่านคลาสConnection
ภายในเท่านั้น คลาสTcpServer
รับประกันว่าจะปล่อยการเชื่อมต่อที่ใช้ConnectionInterface
และใช้คลาสConnection
ภายในเพื่อแสดงทรัพยากรพื้นฐานเหล่านี้ หากคุณใช้ServerInterface
แบบกำหนดเองและเหตุการณ์connection
ไม่เป็นไปตามข้อกำหนดนี้SecureServer
จะปล่อยเหตุการณ์error
แล้วปิดการเชื่อมต่อพื้นฐาน
คลาส UnixServer
ใช้ ServerInterface
และรับผิดชอบในการยอมรับการเชื่อมต่อบนซ็อกเก็ตโดเมน Unix (UDS)
$ server = new React Socket UnixServer ( ' /tmp/server.sock ' );
ตามที่กล่าวไว้ข้างต้น พารามิเตอร์ $uri
สามารถประกอบด้วยเฉพาะพาธของซ็อกเก็ตหรือพาธของซ็อกเก็ตที่นำหน้าด้วยรูปแบบ unix://
หาก URI ที่กำหนดดูเหมือนว่าถูกต้อง แต่การฟังนั้นล้มเหลว (เช่น หากซ็อกเก็ตมีการใช้งานอยู่แล้ว หรือไฟล์ไม่สามารถเข้าถึงได้ ฯลฯ) มันจะส่ง RuntimeException
:
$ first = new React Socket UnixServer ( ' /tmp/same.sock ' );
// throws RuntimeException because socket is already in use
$ second = new React Socket UnixServer ( ' /tmp/same.sock ' );
โปรดทราบว่าเงื่อนไขข้อผิดพลาดเหล่านี้อาจแตกต่างกันไปขึ้นอยู่กับระบบและ/หรือการกำหนดค่าของคุณ โดยเฉพาะอย่างยิ่ง Zend PHP จะรายงานเฉพาะ "ข้อผิดพลาดที่ไม่รู้จัก" เมื่อมีเส้นทาง UDS อยู่แล้วและไม่สามารถผูกไว้ได้ คุณอาจต้องการตรวจสอบ
is_file()
บนเส้นทาง UDS ที่กำหนดเพื่อรายงานข้อความแสดงข้อผิดพลาดที่เป็นมิตรต่อผู้ใช้มากขึ้นในกรณีนี้ ดูข้อความข้อยกเว้นและรหัสสำหรับรายละเอียดเพิ่มเติมเกี่ยวกับเงื่อนไขข้อผิดพลาดจริง
คลาสนี้รับพารามิเตอร์ทางเลือก LoopInterface|null $loop
ที่สามารถใช้เพื่อส่งผ่านอินสแตนซ์ลูปเหตุการณ์เพื่อใช้สำหรับอ็อบเจ็กต์นี้ คุณสามารถใช้ค่า null
ที่นี่เพื่อใช้การวนซ้ำเริ่มต้น ไม่ควรระบุค่านี้ เว้นแต่คุณแน่ใจว่าต้องการใช้อินสแตนซ์ลูปเหตุการณ์ที่กำหนดอย่างชัดเจน
เมื่อใดก็ตามที่ไคลเอนต์เชื่อมต่อ มันจะปล่อยเหตุการณ์ connection
กับอินสแตนซ์การเชื่อมต่อที่ใช้ ConnectionInterface
:
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' New connection ' . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
ดูเพิ่มเติมที่ ServerInterface
สำหรับรายละเอียดเพิ่มเติม
การตกแต่ง LimitingServer
จะล้อม ServerInterface
ที่กำหนด และมีหน้าที่รับผิดชอบในการจำกัดและติดตามการเชื่อมต่อที่เปิดไปยังอินสแตนซ์เซิร์ฟเวอร์นี้
เมื่อใดก็ตามที่เซิร์ฟเวอร์พื้นฐานส่งเสียงเหตุการณ์ connection
มันจะตรวจสอบขีดจำกัดของมันและจากนั้นอย่างใดอย่างหนึ่ง
connection
error
แทนเมื่อใดก็ตามที่การเชื่อมต่อปิดลง การเชื่อมต่อนี้จะลบออกจากรายการการเชื่อมต่อที่เปิดอยู่
$ server = new React Socket LimitingServer ( $ server , 100 );
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
ดูตัวอย่างที่สองสำหรับรายละเอียดเพิ่มเติม
คุณต้องผ่านการเชื่อมต่อที่เปิดอยู่ตามจำนวนสูงสุดเพื่อให้แน่ใจว่าเซิร์ฟเวอร์จะปฏิเสธ (ปิด) การเชื่อมต่อโดยอัตโนมัติเมื่อเกินขีดจำกัดนี้ ในกรณีนี้ จะปล่อยเหตุการณ์ error
เพื่อแจ้งให้ทราบ และจะไม่มีการปล่อยเหตุการณ์ connection
$ server = new React Socket LimitingServer ( $ server , 100 );
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
คุณอาจผ่านขีดจำกัด null
เพื่อที่จะไม่จำกัดจำนวนการเชื่อมต่อที่เปิดอยู่ และให้ยอมรับการเชื่อมต่อใหม่ต่อไปจนกว่าคุณจะใช้ทรัพยากรระบบปฏิบัติการหมด (เช่น ตัวจัดการไฟล์ที่เปิด) สิ่งนี้อาจมีประโยชน์หากคุณไม่ต้องการดูแลเรื่องการใช้ขีดจำกัดแต่ยังคงต้องการใช้เมธอด getConnections()
คุณสามารถเลือกกำหนดค่าเซิร์ฟเวอร์ให้หยุดการยอมรับการเชื่อมต่อใหม่ชั่วคราวเมื่อถึงขีดจำกัดการเชื่อมต่อ ในกรณีนี้ เซิร์ฟเวอร์จะหยุดชั่วคราว และไม่ประมวลผลการเชื่อมต่อใหม่ใดๆ อีกต่อไป จึงไม่ปิดการเชื่อมต่อที่มากเกินไปอีกต่อไป ระบบปฏิบัติการพื้นฐานมีหน้าที่รับผิดชอบในการรักษา Backlog ของการเชื่อมต่อที่รอดำเนินการจนกว่าจะถึงขีดจำกัด ซึ่ง ณ จุดนี้จะเริ่มปฏิเสธการเชื่อมต่อเพิ่มเติม เมื่อเซิร์ฟเวอร์ต่ำกว่าขีดจำกัดการเชื่อมต่อ เซิร์ฟเวอร์จะยังคงใช้การเชื่อมต่อจาก Backlog และจะประมวลผลข้อมูลคงค้างใดๆ ในแต่ละการเชื่อมต่อ โหมดนี้อาจมีประโยชน์สำหรับโปรโตคอลบางตัวที่ออกแบบมาเพื่อรอข้อความตอบกลับ (เช่น HTTP) แต่อาจมีประโยชน์น้อยกว่าสำหรับโปรโตคอลอื่นที่ต้องการการตอบกลับทันที (เช่น ข้อความ "ยินดีต้อนรับ" ในการแชทแบบโต้ตอบ)
$ server = new React Socket LimitingServer ( $ server , 100 , true );
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
เมธอด getConnections(): ConnectionInterface[]
สามารถใช้เพื่อส่งคืนอาร์เรย์ที่มีการเชื่อมต่อที่ใช้งานอยู่ทั้งหมดในปัจจุบัน
foreach ( $ server -> getConnection () as $ connection ) {
$ connection -> write ( ' Hi! ' );
}
ConnectorInterface
มีหน้าที่รับผิดชอบในการจัดหาอินเทอร์เฟซสำหรับสร้างการเชื่อมต่อแบบสตรีมมิ่ง เช่น การเชื่อมต่อ TCP/IP ปกติ
นี่คืออินเทอร์เฟซหลักที่กำหนดไว้ในแพ็คเกจนี้ และถูกใช้ทั่วทั้งระบบนิเวศอันกว้างใหญ่ของ React
ส่วนประกอบระดับสูงกว่าส่วนใหญ่ (เช่น HTTP ฐานข้อมูล หรือไคลเอ็นต์บริการเครือข่ายอื่นๆ) ยอมรับอินสแตนซ์ที่ใช้อินเทอร์เฟซนี้เพื่อสร้างการเชื่อมต่อ TCP/IP ไปยังบริการเครือข่ายพื้นฐาน โดยปกติจะทำผ่านการฉีดการขึ้นต่อกัน ดังนั้นจึงค่อนข้างง่ายที่จะสลับการใช้งานนี้กับการใช้งานอื่น ๆ ของอินเทอร์เฟซนี้
อินเทอร์เฟซมีวิธีการเดียวเท่านั้น:
สามารถใช้เมธอด connect(string $uri): PromiseInterface<ConnectionInterface>
เพื่อสร้างการเชื่อมต่อแบบสตรีมมิ่งไปยังที่อยู่ระยะไกลที่กำหนด
มันส่งคืนสัญญาซึ่งปฏิบัติตามสตรีมที่ใช้ ConnectionInterface
เมื่อสำเร็จหรือปฏิเสธโดยมี Exception
หากการเชื่อมต่อไม่สำเร็จ:
$ connector -> connect ( ' google.com:443 ' )-> then (
function ( React Socket ConnectionInterface $ connection ) {
// connection successfully established
},
function ( Exception $ error ) {
// failed to connect due to $error
}
);
ดูเพิ่มเติม ConnectionInterface
สำหรับรายละเอียดเพิ่มเติม
สัญญาที่ส่งคืนจะต้องดำเนินการในลักษณะที่สามารถยกเลิกได้เมื่อยังคงค้างอยู่ การยกเลิกสัญญาที่ค้างอยู่ต้องปฏิเสธมูลค่าด้วย Exception
ควรล้างทรัพยากรและข้อมูลอ้างอิงที่เกี่ยวข้องตามความเหมาะสม:
$ promise = $ connector -> connect ( $ uri );
$ promise -> cancel ();
คลาส Connector
เป็นคลาสหลักในแพ็คเกจนี้ที่ใช้ ConnectorInterface
และอนุญาตให้คุณสร้างการเชื่อมต่อแบบสตรีมมิ่ง
คุณสามารถใช้ตัวเชื่อมต่อนี้เพื่อสร้างการเชื่อมต่อสตรีมมิ่งประเภทใดก็ได้ เช่น TCP/IP แบบข้อความธรรมดา TLS ที่ปลอดภัย หรือสตรีมการเชื่อมต่อ Unix ภายในเครื่อง
มันเชื่อมโยงกับลูปเหตุการณ์หลักและสามารถใช้ได้ดังนี้:
$ connector = new React Socket Connector ();
$ connector -> connect ( $ uri )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
}, function ( Exception $ e ) {
echo ' Error: ' . $ e -> getMessage () . PHP_EOL ;
});
ในการสร้างการเชื่อมต่อ TCP/IP แบบข้อความธรรมดา คุณสามารถส่งผ่านโฮสต์และพอร์ตรวมกันได้ดังนี้:
$ connector -> connect ( ' www.google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
หากคุณไม่ระบุรูปแบบ URI ใน URI ปลายทาง ระบบจะถือว่า
tcp://
เป็นค่าเริ่มต้น และสร้างการเชื่อมต่อ TCP/IP แบบข้อความธรรมดา โปรดทราบว่าการเชื่อมต่อ TCP/IP จำเป็นต้องมีโฮสต์และส่วนพอร์ตใน URI ปลายทางเหมือนด้านบน ส่วนประกอบ URI อื่นๆ ทั้งหมดจะเป็นทางเลือก
ในการสร้างการเชื่อมต่อ TLS ที่ปลอดภัย คุณสามารถใช้รูปแบบ tls://
URI ได้ดังนี้:
$ connector -> connect ( ' tls://www.google.com:443 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
ในการสร้างการเชื่อมต่อซ็อกเก็ตโดเมน Unix ในเครื่อง คุณสามารถใช้รูปแบบ unix://
URI ได้ดังนี้:
$ connector -> connect ( ' unix:///tmp/demo.sock ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
เมธอด
getRemoteAddress()
จะส่งคืนพาธ Unix domain socket (UDS) เป้าหมายตามที่กำหนดให้กับเมธอดconnect()
รวมถึงรูปแบบunix://
เช่นunix:///tmp/demo.sock
เมธอดgetLocalAddress()
มักจะส่งคืนค่าnull
เนื่องจากค่านี้ใช้ไม่ได้กับการเชื่อมต่อ UDS ที่นี่
ภายใต้ฝากระโปรง Connector
ถูกนำมาใช้เป็น ส่วนหน้าของระดับที่สูงกว่า สำหรับตัวเชื่อมต่อระดับล่างที่ใช้ในแพ็คเกจนี้ ซึ่งหมายความว่ายังแชร์คุณสมบัติและรายละเอียดการใช้งานทั้งหมดด้วย หากคุณต้องการพิมพ์คำแนะนำในการใช้งานโปรโตคอลระดับสูงกว่า คุณควรใช้ ConnectorInterface
ทั่วไปแทน
ตั้งแต่ v1.4.0
เป็นต้นไป คลาส Connector
จะใช้อัลกอริทึม happy eyeballs เพื่อเชื่อมต่อผ่าน IPv4 หรือ IPv6 โดยอัตโนมัติเมื่อตั้งชื่อโฮสต์ การดำเนินการนี้จะพยายามเชื่อมต่อโดยอัตโนมัติโดยใช้ทั้ง IPv4 และ IPv6 ในเวลาเดียวกัน (แนะนำให้ใช้ IPv6) จึงหลีกเลี่ยงปัญหาปกติที่ผู้ใช้ต้องเผชิญด้วยการเชื่อมต่อหรือการตั้งค่า IPv6 ที่ไม่สมบูรณ์ หากคุณต้องการเปลี่ยนกลับเป็นลักษณะการทำงานแบบเก่าที่ทำเพียงการค้นหา IPv4 และพยายามเชื่อมต่อ IPv4 เดียวเท่านั้น คุณสามารถตั้งค่า Connector
ได้ดังนี้:
$ connector = new React Socket Connector ([
' happy_eyeballs ' => false
]);
ในทำนองเดียวกัน คุณยังสามารถส่งผลต่อลักษณะการทำงานของ DNS เริ่มต้นได้ดังนี้ คลาส Connector
จะพยายามตรวจจับการตั้งค่า DNS ของระบบของคุณ (และใช้เซิร์ฟเวอร์ DNS สาธารณะของ Google 8.8.8.8
เป็นทางเลือกหากไม่สามารถระบุการตั้งค่าระบบของคุณได้) เพื่อแก้ไขชื่อโฮสต์สาธารณะทั้งหมดเป็นที่อยู่ IP พื้นฐานตามค่าเริ่มต้น หากคุณต้องการใช้เซิร์ฟเวอร์ DNS แบบกำหนดเองอย่างชัดเจน (เช่น การส่งต่อ DNS ภายในหรือเซิร์ฟเวอร์ DNS ทั่วทั้งบริษัท) คุณสามารถตั้ง Connector
ได้ดังนี้:
$ connector = new React Socket Connector ([
' dns ' => ' 127.0.1.1 '
]);
$ connector -> connect ( ' localhost:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
หากคุณไม่ต้องการใช้ตัวแก้ไข DNS เลย และต้องการเชื่อมต่อกับที่อยู่ IP เท่านั้น คุณสามารถตั้ง Connector
ของคุณได้ดังนี้:
$ connector = new React Socket Connector ([
' dns ' => false
]);
$ connector -> connect ( ' 127.0.0.1:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
ขั้นสูง: หากคุณต้องการอินสแตนซ์ DNS ReactDnsResolverResolverInterface
แบบกำหนดเอง คุณสามารถตั้งค่า Connector
ของคุณได้ดังนี้:
$ dnsResolverFactory = new React Dns Resolver Factory ();
$ resolver = $ dnsResolverFactory -> createCached ( ' 127.0.1.1 ' );
$ connector = new React Socket Connector ([
' dns ' => $ resolver
]);
$ connector -> connect ( ' localhost:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
ตามค่าเริ่มต้น รูปแบบ tcp://
และ tls://
URI จะใช้ค่าการหมดเวลาซึ่งเป็นไปตามการตั้ง default_socket_timeout
ini ของคุณ (ซึ่งเป็นค่าเริ่มต้นที่ 60) หากคุณต้องการค่าการหมดเวลาที่กำหนดเอง คุณสามารถส่งผ่านได้ดังนี้:
$ connector = new React Socket Connector ([
' timeout ' => 10.0
]);
ในทำนองเดียวกัน หากคุณไม่ต้องการใช้การหมดเวลาเลยและปล่อยให้ระบบปฏิบัติการจัดการเรื่องนี้ คุณสามารถส่งแฟล็กบูลีนดังนี้:
$ connector = new React Socket Connector ([
' timeout ' => false
]);
ตามค่าเริ่มต้น Connector
ต่อรองรับรูปแบบ tcp://
, tls://
และ unix://
URI หากคุณต้องการห้ามสิ่งเหล่านี้อย่างชัดเจน คุณสามารถส่งแฟล็กบูลีนได้ดังนี้:
// only allow secure TLS connections
$ connector = new React Socket Connector ([
' tcp ' => false ,
' tls ' => true ,
' unix ' => false ,
));
$ connector -> connect ( ' tls://google.com:443 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
tcp://
และ tls://
ยังยอมรับตัวเลือกบริบทเพิ่มเติมที่ส่งไปยังตัวเชื่อมต่อที่สำคัญ หากคุณต้องการส่งผ่านตัวเลือกบริบทเพิ่มเติมอย่างชัดเจน คุณสามารถส่งผ่านอาร์เรย์ของตัวเลือกบริบทได้ดังนี้:
// allow insecure TLS connections
$ connector = new React Socket Connector ([
' tcp ' => [
' bindto ' => ' 192.168.0.1:0 '
],
' tls ' => [
' verify_peer ' => false ,
' verify_peer_name ' => false
],
]);
$ connector -> connect ( ' tls://localhost:443 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
ตามค่าเริ่มต้น ตัวเชื่อมต่อนี้รองรับ TLSv1.0+ และไม่รวมการสนับสนุน SSLv2/SSLv3 รุ่นเก่า คุณยังสามารถเลือกเวอร์ชัน TLS ที่คุณต้องการเจรจากับฝ่ายระยะไกลได้อย่างชัดเจน:
$ connector = new React Socket Connector ([
' tls ' => [
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
]
]);
สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับตัวเลือกบริบท โปรดดูเอกสารประกอบ PHP เกี่ยวกับตัวเลือกบริบทของซ็อกเก็ตและตัวเลือกบริบท SSL
ขั้นสูง: ตามค่าเริ่มต้น Connector
ต่อรองรับรูปแบบ tcp://
, tls://
และ unix://
URI ด้วยเหตุนี้ ระบบจะตั้งค่าคลาสตัวเชื่อมต่อที่จำเป็นโดยอัตโนมัติ หากคุณต้องการส่งผ่านตัวเชื่อมต่อแบบกำหนดเองอย่างชัดเจนสำหรับสิ่งเหล่านี้ คุณสามารถส่งอินสแตนซ์ที่ใช้ ConnectorInterface
ได้ดังนี้:
$ dnsResolverFactory = new React Dns Resolver Factory ();
$ resolver = $ dnsResolverFactory -> createCached ( ' 127.0.1.1 ' );
$ tcp = new React Socket HappyEyeBallsConnector ( null , new React Socket TcpConnector (), $ resolver );
$ tls = new React Socket SecureConnector ( $ tcp );
$ unix = new React Socket UnixConnector ();
$ connector = new React Socket Connector ([
' tcp ' => $ tcp ,
' tls ' => $ tls ,
' unix ' => $ unix ,
' dns ' => false ,
' timeout ' => false ,
]);
$ connector -> connect ( ' google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
ภายใน ตัวเชื่อมต่อ
tcp://
จะถูกรวมไว้โดยตัวแก้ไข DNS เสมอ เว้นแต่คุณจะปิดใช้งาน DNS เหมือนในตัวอย่างข้างต้น ในกรณีนี้ ตัวเชื่อมต่อtcp://
จะได้รับชื่อโฮสต์จริง แทนที่จะรับเฉพาะที่อยู่ IP ที่ได้รับการแก้ไขแล้ว จึงมีหน้าที่รับผิดชอบในการดำเนินการค้นหา ภายใน ตัวเชื่อมต่อtls://
ที่สร้างขึ้นโดยอัตโนมัติจะรวมตัวเชื่อมต่อtcp://
พื้นฐานไว้เสมอสำหรับการสร้างการเชื่อมต่อ TCP/IP แบบข้อความธรรมดาพื้นฐานก่อนที่จะเปิดใช้งานโหมด TLS ที่ปลอดภัย หากคุณต้องการใช้ตัวเชื่อมต่อtcp://
พื้นฐานแบบกำหนดเองสำหรับการเชื่อมต่อ TLS ที่ปลอดภัยเท่านั้น คุณสามารถส่งผ่านตัวเชื่อมต่อtls://
ดังเช่นด้านบนแทนได้อย่างชัดเจน ภายใน ตัวเชื่อมtcp://
และtls://
จะถูกรวมไว้ด้วยTimeoutConnector
เสมอ เว้นแต่คุณจะปิดใช้งานการหมดเวลาเหมือนในตัวอย่างข้างต้น
คลาสนี้รับพารามิเตอร์ทางเลือก LoopInterface|null $loop
ที่สามารถใช้เพื่อส่งผ่านอินสแตนซ์ลูปเหตุการณ์เพื่อใช้สำหรับอ็อบเจ็กต์นี้ คุณสามารถใช้ค่า null
ที่นี่เพื่อใช้การวนซ้ำเริ่มต้น ไม่ควรระบุค่านี้ เว้นแต่คุณแน่ใจว่าต้องการใช้อินสแตนซ์ลูปเหตุการณ์ที่กำหนดอย่างชัดเจน
คลาส TcpConnector
ใช้ ConnectorInterface
และอนุญาตให้คุณสร้างการเชื่อมต่อ TCP/IP แบบข้อความธรรมดากับ IP-port-combination ใด ๆ :
$ tcpConnector = new React Socket TcpConnector ();
$ tcpConnector -> connect ( ' 127.0.0.1:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
ดูตัวอย่างด้วย
ความพยายามในการเชื่อมต่อที่รอดำเนินการสามารถยกเลิกได้โดยการยกเลิกสัญญาที่รอดำเนินการดังนี้:
$ promise = $ tcpConnector -> connect ( ' 127.0.0.1:80 ' );
$ promise -> cancel ();
การเรียก cancel()
บนสัญญาที่ค้างอยู่จะปิดทรัพยากรซ็อกเก็ตพื้นฐาน ดังนั้นจะเป็นการยกเลิกการเชื่อมต่อ TCP/IP ที่ค้างอยู่ และปฏิเสธสัญญาผลลัพธ์
คลาสนี้รับพารามิเตอร์ทางเลือก LoopInterface|null $loop
ที่สามารถใช้เพื่อส่งผ่านอินสแตนซ์ลูปเหตุการณ์เพื่อใช้สำหรับอ็อบเจ็กต์นี้ คุณสามารถใช้ค่า null
ที่นี่เพื่อใช้การวนซ้ำเริ่มต้น ไม่ควรระบุค่านี้ เว้นแต่คุณแน่ใจว่าต้องการใช้อินสแตนซ์ลูปเหตุการณ์ที่กำหนดอย่างชัดเจน
คุณสามารถเลือกที่จะส่งตัวเลือกบริบทซ็อกเก็ตเพิ่มเติมไปยังตัวสร้างดังนี้:
$ tcpConnector = new React Socket TcpConnector ( null , [
' bindto ' => ' 192.168.0.1:0 '
]);
โปรดทราบว่าคลาสนี้อนุญาตให้คุณเชื่อมต่อกับการรวมพอร์ต IP เท่านั้น หาก URI ที่ระบุไม่ถูกต้อง ไม่มีที่อยู่ IP และพอร์ตที่ถูกต้อง หรือมีรูปแบบอื่นใด URI ดังกล่าวจะถูกปฏิเสธด้วย InvalidArgumentException
:
หาก URI ที่กำหนดดูเหมือนว่าถูกต้อง แต่การเชื่อมต่อล้มเหลว (เช่น หากโฮสต์ระยะไกลปฏิเสธการเชื่อมต่อ ฯลฯ) URI ดังกล่าวจะถูกปฏิเสธด้วย RuntimeException
หากคุณต้องการเชื่อมต่อกับชื่อโฮสต์-พอร์ต-ชุดค่าผสม โปรดดูบทต่อไปนี้ด้วย
การใช้งานขั้นสูง: ภายใน
TcpConnector
จะจัดสรรทรัพยากร บริบท ว่างสำหรับทรัพยากรสตรีมแต่ละรายการ หาก URI ปลายทางมีพารามิเตอร์การค้นหาhostname
จะใช้ค่าดังกล่าวเพื่อตั้งค่าชื่อเพียร์ TLSSecureConnector
และDnsConnector
ใช้สิ่งนี้เพื่อตรวจสอบชื่อเพียร์ และยังสามารถใช้ได้หากคุณต้องการชื่อเพียร์ TLS แบบกำหนดเอง
คลาส HappyEyeBallsConnector
ใช้งาน ConnectorInterface
และอนุญาตให้คุณสร้างการเชื่อมต่อ TCP/IP แบบข้อความธรรมดากับชื่อโฮสต์-พอร์ต-ชุดค่าผสม ภายในจะใช้อัลกอริทึม happy eyeballs จาก RFC6555
และ RFC8305
เพื่อรองรับชื่อโฮสต์ IPv6 และ IPv4
โดยตกแต่งอินสแตนซ์ TcpConnector
ที่กำหนด เพื่อให้ค้นหาชื่อโดเมนที่กำหนดผ่าน DNS ก่อน (ถ้ามี) จากนั้นจึงสร้างการเชื่อมต่อ TCP/IP พื้นฐานไปยังที่อยู่ IP เป้าหมายที่ได้รับการแก้ไข
ตรวจสอบให้แน่ใจว่าได้ตั้งค่าตัวแก้ไข DNS และตัวเชื่อมต่อ TCP พื้นฐานดังนี้:
$ dnsResolverFactory = new React Dns Resolver Factory ();
$ dns = $ dnsResolverFactory -> createCached ( ' 8.8.8.8 ' );
$ dnsConnector = new React Socket HappyEyeBallsConnector ( null , $ tcpConnector , $ dns );
$ dnsConnector -> connect ( ' www.google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
ดูตัวอย่างด้วย
ความพยายามในการเชื่อมต่อที่รอดำเนินการสามารถยกเลิกได้โดยการยกเลิกสัญญาที่รอดำเนินการดังนี้:
$ promise = $ dnsConnector -> connect ( ' www.google.com:80 ' );
$ promise -> cancel ();
การเรียก cancel()
ตามสัญญาที่ค้างอยู่จะยกเลิกการค้นหา DNS พื้นฐานและ/หรือการเชื่อมต่อ TCP/IP พื้นฐานและปฏิเสธสัญญาผลลัพธ์
คลาสนี้รับพารามิเตอร์ทางเลือก LoopInterface|null $loop
ที่สามารถใช้เพื่อส่งผ่านอินสแตนซ์ลูปเหตุการณ์เพื่อใช้สำหรับอ็อบเจ็กต์นี้ คุณสามารถใช้ค่า null
ที่นี่เพื่อใช้การวนซ้ำเริ่มต้น ไม่ควรระบุค่านี้ เว้นแต่คุณแน่ใจว่าต้องการใช้อินสแตนซ์ลูปเหตุการณ์ที่กำหนดอย่างชัดเจน
การใช้งานขั้นสูง: ภายใน
HappyEyeBallsConnector
อาศัยResolver
เพื่อค้นหาที่อยู่ IP สำหรับชื่อโฮสต์ที่กำหนด จากนั้นจะแทนที่ชื่อโฮสต์ใน URI ปลายทางด้วย IP นี้ และเพิ่มพารามิเตอร์การสืบค้นhostname
ต่อท้าย และส่ง URI ที่อัปเดตนี้ไปยังตัวเชื่อมต่อที่สำคัญ อัลกอริทึม Happy Eye Balls อธิบายการค้นหาที่อยู่ IPv6 และ IPv4 สำหรับชื่อโฮสต์ที่กำหนด ดังนั้นตัวเชื่อมต่อนี้จึงส่งการค้นหา DNS สองครั้งสำหรับบันทึก A และ AAAA จากนั้นจะใช้ที่อยู่ IP ทั้งหมด (ทั้ง v6 และ v4) และพยายามเชื่อมต่อกับที่อยู่ IP ทั้งหมดด้วยช่วงเวลา 50 มิลลิวินาทีในระหว่างนั้น การเปลี่ยนแปลงระหว่างที่อยู่ IPv6 และ IPv4 เมื่อสร้างการเชื่อมต่อแล้ว การค้นหา DNS อื่นๆ ทั้งหมดและความพยายามในการเชื่อมต่อจะถูกยกเลิก
คลาส DnsConnector
ใช้งาน ConnectorInterface
และอนุญาตให้คุณสร้างการเชื่อมต่อ TCP/IP แบบข้อความธรรมดากับชื่อโฮสต์-พอร์ต-ชุดค่าผสม
โดยตกแต่งอินสแตนซ์ TcpConnector
ที่กำหนด เพื่อให้ค้นหาชื่อโดเมนที่กำหนดผ่าน DNS ก่อน (ถ้ามี) จากนั้นจึงสร้างการเชื่อมต่อ TCP/IP พื้นฐานไปยังที่อยู่ IP เป้าหมายที่ได้รับการแก้ไข
ตรวจสอบให้แน่ใจว่าได้ตั้งค่าตัวแก้ไข DNS และตัวเชื่อมต่อ TCP พื้นฐานดังนี้:
$ dnsResolverFactory = new React Dns Resolver Factory ();
$ dns = $ dnsResolverFactory -> createCached ( ' 8.8.8.8 ' );
$ dnsConnector = new React Socket DnsConnector ( $ tcpConnector , $ dns );
$ dnsConnector -> connect ( ' www.google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
ดูตัวอย่างด้วย
ความพยายามในการเชื่อมต่อที่รอดำเนินการสามารถยกเลิกได้โดยการยกเลิกสัญญาที่รอดำเนินการดังนี้:
$ promise = $ dnsConnector -> connect ( ' www.google.com:80 ' );
$ promise -> cancel ();
การเรียก cancel()
ตามสัญญาที่ค้างอยู่จะยกเลิกการค้นหา DNS พื้นฐานและ/หรือการเชื่อมต่อ TCP/IP พื้นฐานและปฏิเสธสัญญาผลลัพธ์
การใช้งานขั้นสูง: ภายใน
DnsConnector
อาศัยReactDnsResolverResolverInterface
เพื่อค้นหาที่อยู่ IP สำหรับชื่อโฮสต์ที่กำหนด จากนั้นจะแทนที่ชื่อโฮสต์ใน URI ปลายทางด้วย IP นี้ และเพิ่มพารามิเตอร์การสืบค้นhostname
ต่อท้าย และส่ง URI ที่อัปเดตนี้ไปยังตัวเชื่อมต่อที่สำคัญ ตัวเชื่อมต่อพื้นฐานจึงมีหน้าที่สร้างการเชื่อมต่อกับที่อยู่ IP เป้าหมาย ในขณะที่พารามิเตอร์การสืบค้นนี้สามารถใช้เพื่อตรวจสอบชื่อโฮสต์ดั้งเดิมและTcpConnector
ใช้เพื่อตั้งค่าชื่อเพียร์ TLS หากระบุhostname
ไว้อย่างชัดเจน พารามิเตอร์การสืบค้นนี้จะไม่ได้รับการแก้ไข ซึ่งอาจมีประโยชน์หากคุณต้องการชื่อเพียร์ TLS ที่กำหนดเอง
คลาส SecureConnector
ใช้งาน ConnectorInterface
และอนุญาตให้คุณสร้างการเชื่อมต่อ TLS ที่ปลอดภัย (เดิมเรียกว่า SSL) ไปยังชื่อโฮสต์-พอร์ต-ชุดค่าผสมใดๆ
ซึ่งทำได้โดยการตกแต่งอินสแตนซ์ DnsConnector
ที่กำหนด โดยให้สร้างการเชื่อมต่อ TCP/IP แบบข้อความธรรมดาก่อน จากนั้นจึงเปิดใช้งานการเข้ารหัส TLS บนสตรีมนี้
$ secureConnector = new React Socket SecureConnector ( $ dnsConnector );
$ secureConnector -> connect ( ' www.google.com:443 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( " GET / HTTP/1.0 rn Host: www.google.com rnrn" );
. . .
});
ดูตัวอย่างด้วย
ความพยายามในการเชื่อมต่อที่รอดำเนินการสามารถยกเลิกได้โดยการยกเลิกสัญญาที่รอดำเนินการเช่นนั้น:
$ promise = $ secureConnector -> connect ( ' www.google.com:443 ' );
$ promise -> cancel ();
การโทร cancel()
ตามสัญญาที่รอดำเนินการจะยกเลิกการเชื่อมต่อ TCP/IP พื้นฐานและ/หรือการเจรจา SSL/TLS และปฏิเสธสัญญาที่เกิดขึ้น
คลาสนี้ใช้พารามิเตอร์ LoopInterface|null $loop
พารามิเตอร์ที่สามารถใช้เพื่อส่งอินสแตนซ์ลูปเหตุการณ์เพื่อใช้สำหรับวัตถุนี้ คุณสามารถใช้ค่า null
ได้ที่นี่เพื่อใช้ลูปเริ่มต้น ไม่ควรได้รับค่านี้เว้นแต่คุณจะแน่ใจว่าคุณต้องการใช้อินสแตนซ์ลูปเหตุการณ์ที่กำหนดอย่างชัดเจน
คุณสามารถเลือกผ่านตัวเลือกบริบท SSL เพิ่มเติมไปยังตัวสร้างเช่นนี้:
$ secureConnector = new React Socket SecureConnector ( $ dnsConnector , null , [
' verify_peer ' => false ,
' verify_peer_name ' => false
]);
โดยค่าเริ่มต้นตัวเชื่อมต่อนี้รองรับ TLSV1.0+ และไม่รวมการสนับสนุนสำหรับ SSLV2/SSLV3 ดั้งเดิม นอกจากนี้คุณยังสามารถเลือกรุ่น TLS ที่คุณต้องการเจรจากับด้านระยะไกลได้อย่างชัดเจน:
$ secureConnector = new React Socket SecureConnector ( $ dnsConnector , null , [
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
]);
การใช้งานขั้นสูง: ภายใน
SecureConnector
อาศัยการตั้งค่า ตัวเลือกบริบท ที่จำเป็นในทรัพยากรสตรีมพื้นฐาน ควรใช้กับTcpConnector
ที่ไหนสักแห่งในสแต็กตัวเชื่อมต่อเพื่อให้สามารถจัดสรรทรัพยากร บริบท ที่ว่างเปล่าสำหรับแต่ละทรัพยากรสตรีมและตรวจสอบชื่อเพียร์ ความล้มเหลวในการทำเช่นนั้นอาจส่งผลให้เกิดข้อผิดพลาดชื่อเพียร์ TLS ไม่ตรงกันหรือยากที่จะติดตามเงื่อนไขการแข่งขันเนื่องจากทรัพยากรสตรีมทั้งหมดจะใช้ทรัพยากร บริบทเริ่มต้น ที่ใช้ร่วมกันเพียงครั้งเดียว
คลาส TimeoutConnector
ใช้ ConnectorInterface
และช่วยให้คุณเพิ่มการจัดการหมดเวลาในอินสแตนซ์ของตัวเชื่อมต่อที่มีอยู่
มันทำได้โดยการตกแต่งอินสแตนซ์ของ ConnectorInterface
ที่กำหนดและเริ่มต้นตัวจับเวลาที่จะปฏิเสธและยกเลิกการเชื่อมต่อโดยอัตโนมัติหากใช้เวลานานเกินไป
$ timeoutConnector = new React Socket TimeoutConnector ( $ connector , 3.0 );
$ timeoutConnector -> connect ( ' google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
// connection succeeded within 3.0 seconds
});
ดูตัวอย่างใด ๆ
คลาสนี้ใช้พารามิเตอร์ LoopInterface|null $loop
พารามิเตอร์ที่สามารถใช้เพื่อส่งอินสแตนซ์ลูปเหตุการณ์เพื่อใช้สำหรับวัตถุนี้ คุณสามารถใช้ค่า null
ได้ที่นี่เพื่อใช้ลูปเริ่มต้น ไม่ควรได้รับค่านี้เว้นแต่คุณจะแน่ใจว่าคุณต้องการใช้อินสแตนซ์ลูปเหตุการณ์ที่กำหนดอย่างชัดเจน
ความพยายามในการเชื่อมต่อที่รอดำเนินการสามารถยกเลิกได้โดยการยกเลิกสัญญาที่รอดำเนินการเช่นนั้น:
$ promise = $ timeoutConnector -> connect ( ' google.com:80 ' );
$ promise -> cancel ();
การโทร cancel()
ตามสัญญาที่รอดำเนินการจะยกเลิกความพยายามการเชื่อมต่อพื้นฐานยกเลิกตัวจับเวลาและปฏิเสธสัญญาที่เกิดขึ้น
คลาส UnixConnector
ใช้ ConnectorInterface
และช่วยให้คุณเชื่อมต่อกับเส้นทาง UNIX Domain Socket (UDS) เช่นนี้:
$ connector = new React Socket UnixConnector ();
$ connector -> connect ( ' /tmp/demo.sock ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( " HELLO n" );
});
การเชื่อมต่อกับซ็อกเก็ตโดเมน UNIX เป็นการดำเนินการอะตอมนั่นคือสัญญาของมันจะชำระ (ไม่ว่าจะแก้ไขหรือปฏิเสธ) ทันที เช่นนี้การโทร cancel()
ตามสัญญาที่เกิดขึ้นไม่มีผล
เมธอด
getRemoteAddress()
จะส่งคืนเส้นทางซ็อกเก็ตโดเมนของ Domain (UDS) ตามวิธีconnect()
ซึ่งเตรียมไว้ล่วงหน้าด้วยunix://
Scheme ตัวอย่างเช่นunix:///tmp/demo.sock
วิธีgetLocalAddress()
ส่วนใหญ่จะส่งคืนค่าnull
เนื่องจากค่านี้ไม่สามารถใช้ได้กับการเชื่อมต่อ UDS ที่นี่
คลาสนี้ใช้พารามิเตอร์ LoopInterface|null $loop
พารามิเตอร์ที่สามารถใช้เพื่อส่งอินสแตนซ์ลูปเหตุการณ์เพื่อใช้สำหรับวัตถุนี้ คุณสามารถใช้ค่า null
ได้ที่นี่เพื่อใช้ลูปเริ่มต้น ไม่ควรได้รับค่านี้เว้นแต่คุณจะแน่ใจว่าคุณต้องการใช้อินสแตนซ์ลูปเหตุการณ์ที่กำหนดอย่างชัดเจน
คลาส FixedUriConnector
ใช้ ConnectorInterface
และตกแต่งตัวเชื่อมต่อที่มีอยู่เพื่อใช้ URI ที่กำหนดไว้ล่วงหน้า
สิ่งนี้มีประโยชน์สำหรับผู้บริโภคที่ไม่รองรับ URIs บางอย่างเช่นเมื่อคุณต้องการเชื่อมต่อกับเส้นทาง UNIX Domain Socket (UDS) อย่างชัดเจนแทนที่จะเชื่อมต่อกับที่อยู่เริ่มต้นที่สันนิษฐานโดย API ระดับสูงกว่า:
$ connector = new React Socket FixedUriConnector (
' unix:///var/run/docker.sock ' ,
new React Socket UnixConnector ()
);
// destination will be ignored, actually connects to Unix domain socket
$ promise = $ connector -> connect ( ' localhost:80 ' );
วิธีที่แนะนำในการติดตั้งไลบรารีนี้คือผ่าน Composer ยังใหม่กับนักแต่งเพลงใช่ไหม?
เมื่อเปิดตัวแล้ว โปรเจ็กต์นี้จะติดตาม SemVer ในขณะนี้จะติดตั้งเวอร์ชันการพัฒนาล่าสุด:
composer require react/socket:^3@dev
ดูเพิ่มเติมที่ CHANGELOG สำหรับรายละเอียดเกี่ยวกับการอัปเกรดเวอร์ชัน
โปรเจ็กต์นี้มีจุดมุ่งหมายเพื่อทำงานบนแพลตฟอร์มใดๆ ดังนั้นจึงไม่จำเป็นต้องมีส่วนขยาย PHP ใดๆ และรองรับการทำงานบน PHP 7.1 จนถึง PHP 8+ ปัจจุบัน ขอแนะนำอย่างยิ่งให้ใช้ PHP เวอร์ชันล่าสุดที่รองรับ สำหรับโปรเจ็กต์นี้
Legacy PHP <7.3.3 (และ PHP <7.2.15) ทนทุกข์ทรมานจากข้อผิดพลาดที่ Feof () อาจบล็อกด้วยการใช้ CPU 100% ในบันทึก TLS ที่กระจัดกระจาย เราพยายามแก้ไขปัญหานี้โดยการบริโภคบัฟเฟอร์รับที่สมบูรณ์พร้อมกันเพื่อหลีกเลี่ยงข้อมูลเก่าในบัฟเฟอร์ TLS สิ่งนี้เป็นที่รู้จักกันว่าทำงานเกี่ยวกับการใช้งาน CPU สูงสำหรับเพื่อนร่วมงานที่มีพฤติกรรมที่ดี แต่สิ่งนี้อาจทำให้เกิดข้อมูลขนาดใหญ่มากสำหรับสถานการณ์ที่มีปริมาณงานสูง พฤติกรรมบั๊กกี้ยังคงสามารถเรียกใช้เนื่องจากบัฟเฟอร์ I/O ของเครือข่ายหรือเพื่อนที่เป็นอันตรายในเวอร์ชันที่ได้รับผลกระทบขอแนะนำให้อัปเกรดเป็นอย่างยิ่ง
Legacy PHP <7.1.4 ทนทุกข์ทรมานจากข้อผิดพลาดเมื่อเขียนข้อมูลชิ้นใหญ่ผ่านสตรีม TLS ในครั้งเดียว เราพยายามแก้ไขปัญหานี้โดยการ จำกัด ขนาดชิ้นเขียนเป็น 8192 ไบต์สำหรับรุ่น PHP รุ่นเก่าเท่านั้น นี่เป็นเพียงการทำงานรอบและมีการลงโทษประสิทธิภาพที่เห็นได้ชัดสำหรับเวอร์ชันที่ได้รับผลกระทบ
หากต้องการรันชุดทดสอบ คุณต้องโคลน repo นี้ก่อน จากนั้นจึงติดตั้งการขึ้นต่อกันทั้งหมดผ่าน Composer:
composer install
หากต้องการรันชุดทดสอบ ให้ไปที่รูทโปรเจ็กต์แล้วรัน:
vendor/bin/phpunit
ชุดทดสอบยังมีการทดสอบการรวมการทำงานจำนวนหนึ่งซึ่งขึ้นอยู่กับการเชื่อมต่ออินเทอร์เน็ตที่มีเสถียรภาพ หากคุณไม่ต้องการเรียกใช้สิ่งเหล่านี้พวกเขาสามารถข้ามไปได้เช่นนี้:
vendor/bin/phpunit --exclude-group internet
MIT โปรดดูไฟล์ลิขสิทธิ์