承接 amphp/socket 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

amphp/socket

Composer 安装命令:

composer require amphp/socket

包简介

Non-blocking socket connection / server implementations based on Amp and Revolt.

README 文档

README

AMPHP is a collection of event-driven libraries for PHP designed with fibers and concurrency in mind. amphp/socket is a library for establishing and encrypting non-blocking sockets. It provides a socket abstraction for clients and servers. It abstracts the really low levels of non-blocking streams in PHP.

Latest Release MIT License

Installation

This package can be installed as a Composer dependency.

composer require amphp/socket

Requirements

amphp/socket heavily relies on amphp/byte-stream, specifically its ReadableStream and WritableStream interfaces.

Connecting to a Server

amphp/socket allows clients to connect to servers via TCP, UDP, or Unix domain sockets. You can establish a socket connection using Amp\Socket\connect(). It will automatically resolve DNS names and retries other IPs if a connection fails and multiple IPs are available.

// You can customize connect() options using ConnectContext
$connectContext = (new Amp\Socket\ConnectContext)
        ->withConnectTimeout(5);

// You can optionally pass a Cancellation object to cancel a pending connect() operation
$deferredCancellation = new Amp\DeferredCancellation();

$socket = connect('amphp.org:80', $connectContext, $deferredCancellation->getCancellation());

Encrypted Connections / TLS

If you want to connect via TLS, use Amp\Socket\connectTls() instead or call $socket->setupTls() on the returned socket.

Handling Connections

Socket implements ReadableStream and WritableStream, so everything from amphp/byte-stream applies for receiving and sending data.

#!/usr/bin/env php
<?php // basic (and dumb) HTTP client

require __DIR__ . '/../vendor/autoload.php';

// This is a very simple HTTP client that just prints the response without parsing.
// league/uri required for this example.

use Amp\ByteStream;
use Amp\Socket\ClientTlsContext;
use Amp\Socket\ConnectContext;
use League\Uri\Http;
use function Amp\Socket\connect;
use function Amp\Socket\connectTls;

$stdout = ByteStream\getStdout();

if (\count($argv) !== 2) {
    $stdout->write('Usage: examples/simple-http-client.php <url>' . PHP_EOL);
    exit(1);
}

$uri = Http::createFromString($argv[1]);
$host = $uri->getHost();
$port = $uri->getPort() ?? ($uri->getScheme() === 'https' ? 443 : 80);
$path = $uri->getPath() ?: '/';

$connectContext = (new ConnectContext)
        ->withTlsContext(new ClientTlsContext($host));

$socket = $uri->getScheme() === 'http'
        ? connect($host . ':' . $port, $connectContext)
        : connectTls($host . ':' . $port, $connectContext);

$socket->write("GET {$path} HTTP/1.1\r\nHost: $host\r\nConnection: close\r\n\r\n");

ByteStream\pipe($socket, $stdout);

Server

amphp/socket allows listening for incoming TCP connections as well as connections via Unix domain sockets. It defaults to secure TLS settings if you decide to enable TLS.

Listening and Accepting Connections

Use Amp\Socket\Socket\listen() to listen on a port or unix domain socket. It's a wrapper around stream_socket_server that gives useful error message on failures via exceptions.

Once you're listening, accept clients using Server::accept(). It returns a Socket that returns once a new client has been accepted. It's usually called within a while loop:

$server = Socket\listen("tcp://127.0.0.1:1337");

while ($client = $server->accept()) {
    // You shouldn't spend too much time here, because that blocks accepting another client, so we use async():
    async(function () use ($client) {
        // Handle client connection here
    });
}

Handling Connections

Socket implements ReadableStream and WritableStream, so everything from amphp/byte-stream applies for receiving and sending data. It's best to handle clients in their own coroutine, while letting the server accept all clients as soon as there are new clients.

#!/usr/bin/env php
<?php // basic (and dumb) HTTP server

require __DIR__ . '/../vendor/autoload.php';

// This is a very simple HTTP server that just prints a message to each client that connects.
// It doesn't check whether the client sent an HTTP request.

// You might notice that your browser opens several connections instead of just one,
// even when only making one request.

use Amp\Socket;
use function Amp\async;

$server = Socket\listen('127.0.0.1:0');

echo 'Listening for new connections on ' . $server->getAddress() . ' ...' . PHP_EOL;
echo 'Open your browser and visit http://' . $server->getAddress() . '/' . PHP_EOL;

while ($socket = $server->accept()) {
    async(function () use ($socket) {
        $address = $socket->getRemoteAddress();
        $ip = $address->getHost();
        $port = $address->getPort();

        echo "Accepted connection from {$address}." . PHP_EOL;

        $body = "Hey, your IP is {$ip} and your local port used is {$port}.";
        $bodyLength = \strlen($body);

        $socket->write("HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Length: {$bodyLength}\r\n\r\n{$body}");
        $socket->end();
    });
}

Closing Connections

Once you're done with a client, close the connection using Socket::close(). If you want to wait for all data to be successfully written before closing the connection, use Socket::end(). See above for an example.

Server Address

Sometimes you don't know the address the server is listening on, e.g. because you listed to tcp://127.0.0.1:0, which assigns a random free port. You can use Server::getAddress() to get the address the server is bound to.

Server Shutdown

Once you're done with the server socket, close the socket. That means, the server won't listen on the specified location anymore. Use Server::close() to close the server socket.

Encrypted Connections / TLS

As already mentioned in the documentation for Amp\Socket\Socket\listen(), you need to enable TLS manually after accepting connections. For a TLS server socket, you listen on the tcp:// protocol on a specified address. After accepting clients, call $socket->setupTls() where $socket is the socket returned from SocketServer::accept().

Warning Any data transmitted before Socket::setupTls() completes will be transmitted in clear text. Don't attempt to read from the socket or write to it manually. Doing so will read the raw TLS handshake data that's supposed to be read by OpenSSL.

Self-Signed Certificates

There's no option to allow self-signed certificates in ClientTlsContext since it is no more secure than disabling peer verification. To safely use a self-signed certificate, disable peer verification and require fingerprint verification of the certificate using ClientTlsContext::withPeerFingerprint().

Security

If you discover any security related issues, please email me@kelunik.com instead of using the issue tracker.

License

The MIT License (MIT). Please see LICENSE for more information.

amphp/socket 适用场景与选型建议

amphp/socket 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 46.37M 次下载、GitHub Stars 达 266, 最近一次更新时间为 2015 年 08 月 03 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「sockets」 「tcp」 「encryption」 「async」 「tls」 「non-blocking」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 amphp/socket 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 amphp/socket 我们能提供哪些服务?
定制开发 / 二次开发

基于 amphp/socket 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 46.37M
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 267
  • 点击次数: 50
  • 依赖项目数: 137
  • 推荐数: 2

GitHub 信息

  • Stars: 266
  • Watchers: 12
  • Forks: 37
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2015-08-03