php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #63293 Add support to establish > 1 persistent connection to the same UNIX socket
Submitted: 2012-10-16 19:12 UTC Modified: 2012-10-17 10:39 UTC
Votes:7
Avg. Score:4.9 ± 0.3
Reproduced:5 of 6 (83.3%)
Same Version:2 (40.0%)
Same OS:5 (100.0%)
From: samm at os2 dot kiev dot ua Assigned:
Status: Open Package: Streams related
PHP Version: master-Git-2012-10-16 (Git) OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: samm at os2 dot kiev dot ua
New email:
PHP Version: OS:

 

 [2012-10-16 19:12 UTC] samm at os2 dot kiev dot ua
Description:
------------
I found that it is possible to establish > 1 persistent connections with unique_id to TCP socket using syntax provided below:

$s1=stream_socket_client('tcp://127.0.0.1:1234/id1', $errno, $errstr, 3, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT);

$s2=stream_socket_client('tcp://127.0.0.1:1234/id2', $errno, $errstr, 3, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT);


id1 and id2 are an unique identifiers which i can use later. This way i can use > 1 persistent connection to the same host->port. Unfortunately it does not work for the UNIX socket type. My proposed change is to add optional columnn (:) to the UNIX socket and use it as identifier. E.g. 

$s1=stream_socket_client('unix:////var/run/unix.sock:id1', $errno, $errstr, 3, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT);
$s2=stream_socket_client('unix:////var/run/unix.sock:id2', $errno, $errstr, 3, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT);

Part before column is used as socket path name, path after columnt - as connection id.

Test script:
---------------
<?php
$sock = stream_socket_client('unix:////var/run/unix.sock:234', $errno, $errstr, 3, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT);
if($errno) echo $errstr."\n";
$sock2 = stream_socket_client('unix:////var/run/unix.sock:123', $errno, $errstr, 3, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT);
if($errno) echo $errstr."\n";
// here we can use "netstat -an|grep unix.sock"  to control number of established connections
sleep(1000));
?>


Expected result:
----------------
no connection errors and 2 different connections

Actual result:
--------------
connection error

Patches

add-column-to-unixsocket (last revision 2012-10-16 19:14 UTC by samm at os2 dot kiev dot ua)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-10-17 10:39 UTC] cataphract@php.net
-Package: Sockets related +Package: Streams related
 [2012-10-22 09:50 UTC] sskaje at gmail dot com
Similar feature/change request, but for persistent id customization support for 
stream_socket_client().

I wrote some code as an APNS client which uses stream_socket_client() and have 
STREAM_CLIENT_PERSISTENT on. But if I need more than one client certificate to 
make my code working as a service for more than one app, I have to create 
different stream context. 

The problem is, 

In ext/standard/streamsfuncs.c (ver 5.4.8)

 109     if (flags & PHP_STREAM_CLIENT_PERSISTENT) {
 110         spprintf(&hashkey, 0, "stream_socket_client__%s", host);
 111     }

and 

 131     stream = php_stream_xport_create(host, host_len, REPORT_ERRORS,
 132             STREAM_XPORT_CLIENT | (flags & PHP_STREAM_CLIENT_CONNECT ? 
STREAM_XPORT_CONNECT : 0) |
 133             (flags & PHP_STREAM_CLIENT_ASYNC_CONNECT ? 
STREAM_XPORT_CONNECT_ASYNC : 0),
 134             hashkey, &tv, context, &errstr, &err);

'hashkey' is used as a persistent id for connections, in fact, one same hashkey 
shared by many '$context's.

Additional parameter is requested to customize the persistent id use by 
php_stream_xport_create().


Sample Code:
class spSimpleAPNS{
...
	protected function connect($key)
	{
		# Create Context
		$ctx = stream_context_create();
		stream_context_set_option($ctx, 'ssl', 'local_cert', $this-
>cert_path);

		#
		# Push
		$fp = stream_socket_client($this->servers[$this->dev_mode ? 
'sandbox' : 'product'][$key], $errno, $error, 100, 
(STREAM_CLIENT_CONNECT|PHP_STREAM_CLIENT_PERSISTENT), $ctx);
		stream_set_blocking($fp, 0);
        ...
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Oct 06 13:01:27 2024 UTC