테스트 사이트 - 개발 중인 베타 버전입니다

golang으로 PHP와 통신하기

· 2년 전 · 1054 · 6

Golang으로 PHP와 통신하기


처음에는 PHP Extension으로 구현하고자 했습니다. 하지만 잘 작동하지 않았습니다. 방법을 달리 해야겠더라구요.

그래서 찾은 게 RPC(remote procedure call) 이라는 프로세스간 통신 기술을 찾았습니다.

roadrunner-server/goridge 라는 Go 라이브러리를 이용하여 PHP와 통신을 해봅시다.

1. Go 프로그래밍
  • 프로그래밍 하기에 앞서 필요한 라이브러리를 받아야 합니다.

    go get github.com/roadrunner-server/goridge

  • 그 후 프로그래밍을 해봅시다.

package main

import (
  "fmt"
  "net"
  "net/rpc"
  "log"
  
  goridgeRpc "github.com/roadrunner-server/goridge/v3/pkg/rpc"
)

// App 구조체는 PHP에서 메서드를 불러올 때 필요합니다.
// 메서드를 구현할 때 사용되기 때문입니다.
type App struct{}

// Hi 메서드는 App 구조체를 위한 메서드입니다. 
// 필요할 때 App 구조체에 정의된 필드를 사용 할 수 있습니다.
// *r 에 문자열을 담으면 PHP에서 표현되는 방식입니다.
func (a *App) Hi(name string, r *string) error {
  *r = fmt.Sprintf("Hello, %s!", name)
  return nil // PHP에서 Fatal error를 방지하고자 nil(null) 을 리턴합니다.
}

func main() {
  ln, err := net.Listen("tcp", ":6001")
  // TCP 6001 포트를 열었으나 에러가 발생할 경우 프로그램을 종료시킵니다.
  if err != nil {
    panic(err)
  }
  
  err = rpc.Register(new(App))
  // 수신자 메서드를 서버에 게시하는 도중 에러가 발생할 경우
  // 프로그램을 종료시킵니다.
  // ps. 주로 메서드 구현할 때 에러가 있을 경우(ex. 메서드에 2개 이상의 인자가 있을 경우)
  if err != nil {
    panic(err)
  }
  log.Printf("started\n")
  
  for {
    conn, err := ln.Accept()
    // 에러가 발생하더라도 진행
    if err != nil {
      continue
    }
    
    log.Printf("new connection %+v", conn)
    go rpc.ServeCode(goridgeRpc.NewCodec(conn))
  }
}

매우 단순합니다. 앞으로 개발하면서 구현할 건 메서드나 구조체밖에 없을 정도입니다.

이제 이 코드를 리눅스, 윈도우, 맥 환경에 맞게 빌드하여 서버로 전달하여 실행시키면 됩니다.

참고로 포트를 열었으니 해당 포트에 외부 접속이 가능하다면 서버를 분리시킬 수 있겠군요.

2. PHP 프로그래밍

Go에서 사용했던 패키지와 마찬가지로 PHP에서도 패키지를 사용하겠습니다.

$ composer require spiral/goridge
<?php
use Spiral\Goridge;
require "vendor/autoload.php";

$rpc = new Goridge\RPC\RPC(
  Goridge\Relay::create('tcp://127.0.0.1:6001')
);

echo $rpc->call("App.Hi", "Anthony");
?>

이렇게 해서 $rpc->call 의 1번째 인자에는 App.메서드를 호출하고 2번째 인자에 값을 담아 호출하면 됩니다. ps. 값이 하나밖에 안되더라구요. 쩝.

3. 결과보기

1030332716_1678866864.3749.png

이처럼 출력이 됩니다.

 

이걸 이용해서 PHP만으로는 어려웠던 걸 Golang의 힘을 빌려 사용할 수 있겠네요.

물론 다는 안되겠지만...

댓글 작성

댓글을 작성하시려면 로그인이 필요합니다.

로그인하기

댓글 6개

그냥 restapi 쓰는것도 ...나쁘지 않을것 같네요.
물론 속도는 rpc가 훨씬 빠릅니다.
요즘 많이 쓰는건 grpc.

php는 grpc listen 을 하기가 어려워서 (서버소켓 필요)
http restapi 가 가장 좋은 방법일거 같네요.
@솔그루 생각해보니 그러네요.
처음엔 restapi를 할려면 서버가 필요하니 그닥..?? 이라고 생각했는데 어차피 rpc도 포트하나 열어서 대기하는 건 마찬가지니깐..

게다가 gobridge 는 인자를 하나만 넣을 수 있더라구요. 수정하면 뭐 여러개까지 가능하겠지만...

그런 측면에서는 gobridge를 이용한 rpc보다는 rest가 훨씬 범용성도 좋고 쉽게 개발도 할 수 있네요.

속도는 뭐.. 딸리겠지만 로컬이라면.. 비슷하지 않을까 생각합니다
@GolangKR 요청시 응답시간이 0.1sec 라고 해도,,,,
rpc 는 0.001sec 라고 한다면, 성능은 100배 차이나는거죠.
restapi 도 로컬 호출은 빠르니 문제없는것처럼 보이죠.

요청/응답이 많고 속도가 중요시되는 MSA 구조에서는 gRPC 가 선호됩니다.
2년 전
@솔그루 아하 그렇군요... rest가 아무리 빨라도 rpc가 몇배는 더 빠르니...
gRPC도 천천히 읽어봐야겠네요
2년 전
클라이언트 사이드의 고랭이라면 gopherjs 도 추천드립니다.
2년 전
@자바패드 감사합니다 한번 docs 읽어봐야겠네요

게시글 목록

번호 제목
92
82
80
79
78
77
76
75
72
65
64
63
62
57
55
54
53
52
51
50
46
44
43
39
34
29
28
27
26
22