Skip to content

Commit

Permalink
Add plugins README and pluginserver_example
Browse files Browse the repository at this point in the history
  • Loading branch information
vctt94 committed Jul 17, 2024
1 parent 862bf2f commit c52e784
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 1 deletion.
3 changes: 2 additions & 1 deletion brclient/appstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -2662,7 +2662,7 @@ func (as *appState) handleCmd(rawText string, args []string) {
}
}

// initializePlugins initialize plugins on startup
// initializePlugins sets up plugins in the database during startup.
func (as *appState) initializePlugins() error {
// Retrieve all enabled plugins from the database.
enabledPlugins, err := as.c.GetEnabledPlugins()
Expand Down Expand Up @@ -2693,6 +2693,7 @@ func (as *appState) initializePlugins() error {
return nil
}

// initPlugin initialize plugins so they can listen for updates at the appstate.
func (as *appState) initPlugin(cw *chatWindow, pid clientintf.PluginID, address string) {
req := &grpctypes.PluginStartStreamRequest{
ClientId: as.c.PublicID().Bytes(),
Expand Down
58 changes: 58 additions & 0 deletions clientplugin/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Plugins for Bison Relay

This README provides a comprehensive guide on creating and integrating a plugin server with the Bison Relay client (brclient). The plugin enables interaction with a plugin server over gRPC, facilitating communication and execution of plugin-specific actions.

## Overview

The Plugin Client is designed to interact with a Plugin Server over gRPC using the PluginService Interface.
More information can be found at [pluginrpc.proto](pluginrpc.proto).

It can:
- Initialize a plugin
- Call plugin-specific actions
- Retrieve plugin version information

## Setting Up the Plugin Server

### Step 1: Enable JSON-RPC on brclient

Ensure that JSON-RPC is enabled in your `brclient.conf` file. This allows the plugin client to communicate with the plugin server. Add or update the following lines in the configuration file:

```ini
[clientrpc]
# Enable the JSON-RPC clientrpc protocol on the comma-separated list of addresses.
jsonrpclisten = 127.0.0.1:7676

# Path to the keypair used for running TLS on the clientrpc interfaces.
rpccertpath = ~/.brclient/rpc.cert
rpckeypath = ~/.brclient/rpc.key

# Path to the certificate used as CA for client-side TLS authentication.
rpcclientcapath = ~/.brclient/rpc-ca.cert
```

Implement the gRPC server using the service definition. Here is an example of a basic implementation in Go, found in [plugin server example](examples/pluginserver_example/main.go):

With that, a brclient can connect to other plugin servers. If a brclient is running as a plugin server, other clients can connect to a it, for example:

### Connecting brclient to a Plugin Server

To connect a brclient to the plugin server, use the following commands:

1. **Initialize a Plugin**:

`/plugin init <nick or id> <plugin-cfg>`

This command initializes a new plugin for the specified plugin server allowing it to listen to updates at the brclient appstate.

2. **Get Plugin's Version**:

`/plugin version <nick or id>`

This command retrieves the version information of the plugin associated with the specified server.

3. **Call Plugin Action**:

`/plugin action <nick or id> <action> [<data>]`

This command calls a specific action on the plugin associated with the specified server. The `data` parameter is optional and can be used to pass additional information to the plugin.
47 changes: 47 additions & 0 deletions clientplugin/examples/pluginserver_example/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package main

import (
"context"
"log"
"net"

"github.com/companyzero/bisonrelay/clientplugin/grpctypes"
"google.golang.org/grpc"
)

type pluginServer struct {
grpctypes.UnimplementedPluginServiceServer
}

func (s *pluginServer) Init(req *grpctypes.PluginStartStreamRequest, stream grpctypes.PluginService_InitServer) error {
// Implement your Init logic here
return nil
}

func (s *pluginServer) CallAction(req *grpctypes.PluginCallActionStreamRequest, stream grpctypes.PluginService_CallActionServer) error {
// Implement your CallAction logic here
return nil
}

func (s *pluginServer) GetVersion(ctx context.Context, req *grpctypes.PluginVersionRequest) (*grpctypes.PluginVersionResponse, error) {
// Implement your GetVersion logic here
return &grpctypes.PluginVersionResponse{
AppName: "ExamplePlugin",
AppVersion: "1.0.0",
}, nil
}

func main() {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}

s := grpc.NewServer()
grpctypes.RegisterPluginServiceServer(s, &pluginServer{})

log.Printf("server listening at %v", lis.Addr())
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}

0 comments on commit c52e784

Please sign in to comment.