PHP to Go使用Unix域套接字

时间:2013-08-23 17:16:46

标签: php sockets go ipc

我正在尝试使用Unix套接字让PHP向Go发送IPC消息。一切似乎都有效,除了PHP似乎继续从套接字读取响应,并且不会放手。 (浏览器load-spinner继续运行,并且没有页面呈现。)我在PHP:socket_read()函数中使用标志PHP_NORMAL_READ,并从Go显式发送“\ n”。

在终端中观察Go过程,一切似乎都在这一端正常工作。

编辑:我认为这是一个浏览器缓存问题。如果我发回不同的数据供PHP回应,一切都按预期工作。我也切换到fmt.Fprintln()以确保我没有得到换行错误。

转到:

package main

import (
    "net"
    "fmt"
    "log"
    "os"
)

const socket_addr = "/tmp/odc_ws.sock"

func echoServer(c net.Conn){
    buf := make([]byte, 512)
    size, err := c.Read(buf)
    if err != nil {
        log.Fatal("Read error: ", err)
    }
    data := buf[0:size]     
    fmt.Println("Server received: ", string(data))

    // NEW CODE
    t := time.Now()
    retMsg := fmt.Sprintf("OK+ at %s", t)
    size, err = fmt.Fprintln(c, retMsg)     

    //size, err = c.Write(ok)

    if err == nil{
        fmt.Println("Wrote this many bytes: ", size)
    } else {
        log.Fatal("Write error: ", err)
    }
}

func main(){
    l, err := net.Listen("unix", socket_addr)
    if err != nil{
        fmt.Println("On noes: %s", err)
        return
    }
    defer l.Close()
    for{
        fd, err := l.Accept()
        if err != nil{
            log.Fatal("Accept error", err)
        }
        go echoServer(fd)
    }

}

PHP:

ob_implicit_flush();
$socket_file = "/tmp/odc_ws.sock";

if (($socket = socket_create(AF_UNIX, SOCK_STREAM, 0)) === false) {
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "<br>";
}
if (socket_connect($socket, $socket_file) === false) {
    echo "socket_connect() failed: reason: " . socket_strerror(socket_last_error($sock)) . "<br>";
}

$msg = 'PHP sent Go a message at ' . date('H:i:s');
$write_res = socket_write($socket, $msg, $msg_len = strlen($msg));
if($write_res != $msg_len){
    echo '<div>Socket write error: ' . socket_strerror( socket_last_error($socket) ) . '</div>';
}

while($read = socket_read($socket, 512, PHP_NORMAL_READ)){
    echo "<div>Server says: $read</div>";
}
socket_close($socket);

1 个答案:

答案 0 :(得分:1)

这不是PHP问题;您没有关闭服务器连接,因此PHP继续等待更多数据。添加'1'

defer c.Close()

func echoServer(c net.Conn){ defer c.Close() buf := make([]byte, 512) size, err := c.Read(buf) if err != nil { 是强制PHP_NORMAL_READ读取文本行而不是二进制流。

来自socket_read上的PHP文档(强调我的)

  

socket_read()在成功时将数据作为字符串返回,如果出错则返回FALSE(包括远程主机是否已关闭连接