🧙 High-performance PHP-to-Golang IPC/RPC bridge

High-performance PHP-to-Golang IPC bridge

Latest Stable Version GoDoc Linux macOS Windows Linters Go Report Card Codecov

PHPClasses Innovation Award

Goridge is high performance PHP-to-Golang codec library which works over native PHP sockets and Golang net/rpc package. The library allows you to call Go service methods from PHP with a minimal footprint, structures and []byte support.
PHP source code can be found in this repository: goridge-php


See https://github.com/spiral/roadrunner - High-performance PHP application server, load-balancer and process manager written in Golang

Features

  • no external dependencies or services, drop-in (64bit PHP version required)
  • low message footprint (12 bytes over any binary payload), binary error detection
  • CRC32 header verification
  • sockets over TCP or Unix (ext-sockets is required), standard pipes
  • very fast (300k calls per second on Ryzen 1700X over 20 threads)
  • native net/rpc integration, ability to connect to existed application(s)
  • standalone protocol usage
  • structured data transfer using json
  • []byte transfer, including big payloads
  • service, message and transport level error handling
  • hackable
  • works on Windows
  • unix sockets powered (also on Windows)

Installation

GO111MODULE=on go get github.com/roadrunner-server/goridge/v3

Sample of usage

package main

import (
	"fmt"
	"net"
	"net/rpc"

	goridgeRpc "github.com/roadrunner-server/goridge/v3/pkg/rpc"
)

type App struct{}

func (s *App) Hi(name string, r *string) error {
	*r = fmt.Sprintf("Hello, %s!", name)
	return nil
}

func main() {
	ln, err := net.Listen("tcp", ":6001")
	if err != nil {
		panic(err)
	}

	_ = rpc.Register(new(App))

	for {
		conn, err := ln.Accept()
		if err != nil {
			continue
		}
		_ = conn
		go rpc.ServeCodec(goridgeRpc.NewCodec(conn))
	}
}

License

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

Owner
RoadRunner
RoadRunner is high-performance PHP application server and process manager written in Go and powered with plugins
RoadRunner
Comments
  • Second call is too slow

    Second call is too slow

    Hi. I did: go get "github.com/spiral/goridge" composer require spiral/goridge cd ~/go/src/goridge/vendor/spiral/goridge/examples go run ./

    And ran the folowing script:

    `<?php use Spiral\Goridge; require "vendor/autoload.php";

    $t1 = microtime(true); $rpc = new Goridge\RPC( new Goridge\SocketRelay("127.0.0.1", 6001) ); echo $rpc->call("App.Hi", "Antony"); $t3 = (float)microtime(true) - (float)$t1;

    echo ": $t3 | "; $t1 = microtime(true); echo $rpc->call("App.Hi", "Antony"); $t2 = microtime(true); $t3 = (float)$t2 - (float)$t1; echo ": $t3" . PHP_EOL;`

    I got a result: Hello, Antony!: 0.00071406364440918 | Hello, Antony!: 0.041256904602051 Is it a bug? Or I made mistake?

    ** Thank for your job!

  • Allow Unix socket on Windows

    Allow Unix socket on Windows

    Windows 10 now supports basic functionality of AF_UNIX sockets. Consequently, restriction on Unix sockets on Windows was removed in Go and thus can be removed in goridge.

  • [BUG] RPC error message duplication

    [BUG] RPC error message duplication

    I tried this code:

    <?php
    
    use Spiral\Goridge\RPC\RPC;
    
    require __DIR__ . '/vendor/autoload.php';
    
    RPC::create('tcp://127.0.0.1:6001')
      ->call('unknown-method', null);
    

    I expected to see this happen:

    Error 'rpc: service/method request ill-formed: unknown-method' on tcp://127.0.0.1:6001
    

    Instead, this happened:

    Error 'rpc: service/method request ill-formed: unknown-method; rpc: service/method request ill-formed: unknown-method' on tcp://127.0.0.1:6001
    

    The version of RR used: 2.3.0 (stable)

    Errortrace, Backtrace or Panictrace

    *not required*
    
  • PHP code removed

    PHP code removed

    PHP code now located in spiral/goridge-php repository. So, current state in master branch can be a little bit cleared.

    Yes, I know about #91. But this iteration must be made anyway, I think.

  • Getting ErrorException when the worker is stopped

    Getting ErrorException when the worker is stopped

    In production whenever the worker is being terminated by Roadrunner normally or by stopping the main process, I am getting an ErrorException with the following message:

    unpack(): Type C: not enough input, need 1, have 0
    

    on line: https://github.com/spiral/goridge/blob/c522eec9d8215c6059eeb4647d37003a2726e346/src/StreamRelay.php#L152

    Goridge version: v2.4.4 Roadrunner version: v1.5.1

  • STDIN is not readable

    STDIN is not readable

    Since version 2.2.0 (after execution composer update) i'v got an error:

    resource `in` must be readable in /app/vendor/spiral/goridge/php-src/StreamRelay.php:43
    

    In my code, I create StreamRelay using the following code:

    new \Spiral\Goridge\StreamRelay(\STDIN, \STDOUT);
    

    And got an error, describet above. It happens because since version 2.2.0 this package uses next assert:

        /**
         * Checks if stream is readable.
         *
         * @param resource $stream
         *
         * @return bool
         */
        private function assertReadable($stream): bool
        {
            $meta = stream_get_meta_data($stream);
            return in_array($meta['mode'], ['r', 'r+', 'w+', 'a+', 'x+', 'c+'], true);
        }
    

    Previos checking method was better: $this->assertMode($in, 'r')

    But this method does not allows to use binary safe mode (b), which appended to the STDIN and STDOUT by default:

    $ docker run --rm php:7.3.0-alpine php -r 'var_dump(stream_get_meta_data(\STDIN)["mode"]);'
    string(2) "rb"
    
    $ docker run --rm php:7.2.0-alpine php -r 'var_dump(stream_get_meta_data(\STDIN)["mode"]);'
    string(2) "rb"
    

    So, my applications cannot be started after update =(

  • StreamRelay requires Sockets extension

    StreamRelay requires Sockets extension

    I tried to add metrics into my application and hit into following error:

    roadrunner_1  | WARN[0020] Error: Call to undefined function Spiral\Goridge\socket_create() in /www/vendor/spiral/goridge/php-src/SocketRelay.php:275 
    roadrunner_1  | WARN[0020] Stack trace:                                 
    roadrunner_1  | WARN[0020] #0 /www/vendor/spiral/goridge/php-src/SocketRelay.php(185): Spiral\Goridge\SocketRelay->createSocket() 
    roadrunner_1  | WARN[0020] #1 /www/vendor/spiral/goridge/php-src/SocketRelay.php(88): Spiral\Goridge\SocketRelay->connect() 
    roadrunner_1  | WARN[0020] #2 /www/vendor/spiral/goridge/php-src/RPC.php(47): Spiral\Goridge\SocketRelay->send('metrics.Add\x00\x00\x00\x00...', 20) 
    roadrunner_1  | WARN[0020] #3 /www/vendor/spiral/roadrunner/src/Metrics.php(44): Spiral\Goridge\RPC->call('metrics.Add', Array) 
    roadrunner_1  | WARN[0020] #4 /www/psr-worker.php(29): Spiral\RoadRunner\Metrics->add('app_metric_coun...', 1) 
    roadrunner_1  | WARN[0020] #5 {main}                                    
    

    RR version is 1.4.7. The reason is inexisting Sockets extension.

    Suggestion: to require it in composer.json as "ext/sockets" OR to mention it in documentation and to throw exception if (!extension_loaded('sockets')) in createSocket

    P.S. There are also some json_encode in Spiral\Goridge\RPC, so it's better to add ext/json to require too.

  • Make slice error

    Make slice error

    got a weird error for a service that was already running for a week: when looking at the code it can only be triggered if leftBytes is negative? is that possible?

    data = make([]byte, 0, leftBytes)

    panic: runtime error: makeslice: cap out of range
    goroutine 89191655 [running]:
    github.com/spiral/goridge.(*SocketRelay).Receive(0xc420142330, 0x0, 0x0, 0x0, 0x28, 0xc42047bda0, 0x0, 0x0)
            /Users/jayme/Documents/projects/go/src/github.com/spiral/goridge/socket.go:54 +0x20e
    github.com/spiral/goridge.(*Codec).ReadRequestBody(0xc420346000, 0x0, 0x0, 0x0, 0x0)
            /Users/jayme/Documents/projects/go/src/github.com/spiral/goridge/codec.go:48 +0x48
    net/rpc.(*Server).readRequest(0xc4201360a0, 0x93b520, 0xc420346000, 0x725fc0, 0x992af8, 0x93b520, 0xc420346000, 0x79a91f, 0x28, 0x0, ...)
            /usr/local/Cellar/go/1.9/libexec/src/net/rpc/server.go:547 +0xe1
    net/rpc.(*Server).ServeCodec(0xc4201360a0, 0x93b520, 0xc420346000)
            /usr/local/Cellar/go/1.9/libexec/src/net/rpc/server.go:460 +0x77
    net/rpc.ServeCodec(0x93b520, 0xc420346000)
            /usr/local/Cellar/go/1.9/libexec/src/net/rpc/server.go:669 +0x41
    created by main.main
    
High-performance PHP application server, load-balancer and process manager written in Golang
High-performance PHP application server, load-balancer and process manager written in Golang

RoadRunner is an open-source (MIT licensed) high-performance PHP application server, load balancer, and process manager. It supports running as a serv

Jan 1, 2023
High-performance PHP application server, load-balancer and process manager written in Golang
High-performance PHP application server, load-balancer and process manager written in Golang

RoadRunner is an open-source (MIT licensed) high-performance PHP application server, load balancer, and process manager. It supports running as a serv

Dec 9, 2021
the pluto is a gateway new time, high performance, high stable, high availability, easy to use

pluto the pluto is a gateway new time, high performance, high stable, high availability, easy to use Acknowledgments thanks nbio for providing low lev

Sep 19, 2021
Netpoll is a high-performance non-blocking I/O networking framework, which focused on RPC scenarios, developed by ByteDance.
Netpoll is a high-performance non-blocking I/O networking framework, which focused on RPC scenarios, developed by ByteDance.

Netpoll is a high-performance non-blocking I/O networking framework, which focused on RPC scenarios, developed by ByteDance. RPC is usually heavy on processing logic and therefore cannot handle I/O serially. But Go's standard library net designed blocking I/O API, so that the RPC framework can only follow the One Conn One Goroutine design.

Jan 2, 2023
Antenna RPC is an RPC protocol for distributed computing, it's based on QUIC and Colfer. its currently an WIP.

aRPC - Antenna Remote Procedure Call Antenna remote procedure call (aRPC) is an RPC protocol focused on distributed processing and HPC. aRPC is implem

Jun 16, 2021
rpc/v2 support for JSON-RPC 2.0 Specification.

rpc rpc/v2 support for JSON-RPC 2.0 Specification. gorilla/rpc is a foundation for RPC over HTTP services, providing access to the exported methods of

Jul 4, 2021
Go Substrate RPC Client (GSRPC)Go Substrate RPC Client (GSRPC)

Go Substrate RPC Client (GSRPC) Substrate RPC client in Go. It provides APIs and types around Polkadot and any Substrate-based chain RPC calls. This c

Nov 11, 2021
Simple, fast and scalable golang rpc library for high load

gorpc Simple, fast and scalable golang RPC library for high load and microservices. Gorpc provides the following features useful for highly loaded pro

Dec 19, 2022
A Matrix-iMessage puppeting bridge

A Matrix-iMessage puppeting bridge. The bridge runs on a Mac or jailbroken iPhone (soonâ„¢). A websocket proxy is required to receive appservice events from the homeserver.

Jan 2, 2023
vks is a Vulkan bridge for Go.

vks vks is a Vulkan bridge for Go. The header generator folder contains the code that is used to generate the vulkan bindings. It woks similar to c-fo

Sep 3, 2022
Bridge between mattermost, IRC, gitter, xmpp, slack, discord, telegram, rocketchat, twitch, ssh-chat, zulip, whatsapp, keybase, matrix, microsoft teams, nextcloud, mumble, vk and more with REST API
Bridge between mattermost, IRC, gitter, xmpp, slack, discord, telegram, rocketchat, twitch, ssh-chat, zulip, whatsapp, keybase, matrix, microsoft teams, nextcloud, mumble, vk and more with REST API

bridge between mattermost, IRC, gitter, xmpp, slack, discord, telegram, rocketchat, twitch, ssh-chat, zulip, whatsapp, keybase, matrix, microsoft teams, nextcloud, mumble, vk and more with REST API (mattermost not required!)

Jan 4, 2023
An inline buildpack for deploying a mattermost-irc bridge

Matterbridge-Heroku An inline buildpack for hosting Matterbridge on Heroku. Heroku is a platform for easily deploying applications. A buildpack provid

Nov 26, 2022
Bridge facebook messenger with any service supported by matterbridge

fbridge fbridge bridges facebook messenger with any service supported by matterbridge trough the API interface. fbridge is using fbchat to connect to

Oct 30, 2022
Facebook bridge used with matterbridge

fbridge-asyncio This repo is a fork of fbridge. If you log in to your facebook account from a browser, after you do, it's a good idea to restart fbrid

Aug 7, 2022
Grpc bridge to various mediabank related systems

Mediabank bridge This internal tool enables authenticated gRPC based endpoint for securely communicating with systems like: Telestream Vantage Workflo

Jan 7, 2022
Bridge REMOV will allow you to safely transfer NFT from RMRK to MOVR and backwards

remov Inspiration Our aim is to expand the capabilities of blockchain and make a secure way for transferring NFT between RMRK and MOVR blockchain. The

Dec 5, 2021
Celestia -> EVM bridge

Peggo Peggo is a Go implementation of the Peggy (Gravity Bridge) Orchestrator originally implemented by Injective Labs. Peggo itself is a fork of the

Dec 12, 2022
A REST API for the DN42 registry, written in Go, to provide a bridge between interactive applications and the registry.

dn42regsrv A REST API for the DN42 registry, written in Go, to provide a bridge between interactive applications and registry data. A public instance

Apr 21, 2022
The official repository of the Gravity Bridge Blockchain

Gravity bridge is Cosmos <-> Ethereum bridge designed to run on the Cosmos SDK blockchains like the Cosmos Hub focused on maximum design simplicity an

Dec 27, 2022