Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A new websocket-based ability to enable PyNARS communicate with Web client #36

Merged
merged 4 commits into from
Oct 22, 2023

Conversation

ARCJ137442
Copy link
Contributor

@ARCJ137442 ARCJ137442 commented Oct 18, 2023

Background

This comes from a comment on issue #35, in which I considered to make a websocket-based IO channel for PyNARS based on websockets.

After reading Bowen Xu's reply, I think aio_rpc is related to "socket" rather than "websocket", which is a duplex communication protocol built on modern Web technology.

So aiming to improve the ability of connecting to other clients (such as web browser), I added a new cmd server-websocket to implement this ability, and made it optional with dynamic imports (so there is no need to force changes to PyNARS dependencies).

Overview

Optimized ConsolePlus and some fixes

  • Added "Output History" to record the output of NARS reasoner uses "output event handlers" in Interface.py (by enhances function register_interface)
  • Fixed a syntax bug in Console.py

(New) cmd server-websocket: Set up a WebSocket-based server using package websockets

  • It gives ability to remote control ConsolePlus via WS connection "ws://[server address]:[server port]" (it can be set by user) and input Narsese/cmd, just like directly input on the command line.
  • In addition to receiving messages sent by clients as console input, it also returns the output of NARS reasoners as JSON text, which is in format [{"interface_name": str, "output_type": str, "content": str}, ...]
    • An example shows one OUT and one ANSWER: [{"interface_name": "initial", "output_type": "OUT", "content": "<B-->C>. %1.000;0.900%"}, {"interface_name": "initial", "output_type": "ANSWER", "content": "<B-->C>. %1.000;0.900%"}]

Previews

Test code of client

import asyncio
import websockets

async def main():
    async with websockets.connect("ws://127.0.0.1:8765") as websocket:
        messages = [
            'A --> B.',
            'A --> C.',
            'B --> C?',
            '/waitans',
        ]
        for message in messages:
            await websocket.send(message)
            print(f"Sent: {message}")

        while True:
            response: str = await websocket.recv()
            print(f"Received: {response}")

asyncio.run(main())

Client output

image

Server output

image

- Optimized `ConsolePlus` and some fixes:
  - Fixed a syntax bug in 'Console.py'
  - Added "Output History" to record the output of NARS reasoner uses "output event handlers" in `Interface.py` (by enhances function `register_interface`)
- (NEW) ConsoleWeb: Set up a WebSocket-based server using package `websockets`
  - It gives ability to remote control `ConsolePlus` via WS connection "ws://[server address]:[server port]" (it can be set by user) and input Narsese/cmd, just like directly input on the command line.
  - In addition to receiving messages sent by clients as console input, it also returns the output of NARS reasoners as JSON text, which is in format `{"interface_name": str, "output_type": str, "content": str}`
    - an example output: `{"interface_name": "initial", "output_type": "ANSWER", "content": "<B-->C>. %1.000;0.900%"}`
@ARCJ137442
Copy link
Contributor Author

In additional, I think this websocket service can be flexible connected to morden Web ecology.

A simple local website example

This is an simple website build with native HTML:

<!DOCTYPE html>

<meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1.0">

<html lang="en">
<head>
    <title>PyNARS WebSocket Client V1</title>
</head>

<body>

    <h1>Out</h1>
    <p id="output"></p>

    <h1>In</h1>
    <input type="text" id="input" placeholder="Input Narsese or cmds" value="A --> B.">
    <input type="text" id="address" placeholder="Input Narsese or cmds" value="ws://127.0.0.1:8765">

    <script>
        const input = document.getElementById('input')
        const output = document.getElementById('output')
        const address = document.getElementById('address')

        // Socket Client //
        let socketIO
        function resetInputWS() {
            socketIO?.close()
            socketIO = new WebSocket(address.value)
            if (socketIO) socketIO.onopen = () => {
                output.innerText += `Websocket connection is established to ${address.value}.\n`
                socketIO.onmessage = handleMessage
            }
            output.innerText += `Websocket connection is reset to ${address.value}.\n`
        }

        // Message handler //
        function handleMessage(event) {
            // format: {"interface_name": "initial", "output_type": "ANSWER", "content": "<B-->C>. %1.000;0.900%"}
            let output_data = JSON.parse(event.data)
            output.innerText += `out> ${output_data?.interface_name}: [${output_data?.output_type}] ${output_data?.content}\n`
        }

        // Listeners //
        input.addEventListener('keydown', (event) => {
            if (event.key === 'Enter') {
                socketIO?.send?.(input.value)
                output.innerText += `in> ${input.value}\n`
                input.value = ''
            }
        })
        address.addEventListener('keydown', (event) => {
            if (event.key === 'Enter') {
                resetInputWS()
                event.preventDefault()
            }
        })

        // Initialize //
        resetInputWS()
    </script>
</html>

By using this simple website, we can access PyNARS from any local browser, such as:
100px

And this is just a simple example of a PyNARS web cilent - I think there's a lot potential things to boost PyNARS's flexibility and connectivity.

@ARCJ137442 ARCJ137442 changed the title A new websocket-based PyNARS web server called ConsoleWeb A new websocket-based ability to enable PyNARS communicate with Web client Oct 20, 2023
@bowen-xu bowen-xu merged commit 1f899a4 into opennars:dev Oct 22, 2023
@ARCJ137442 ARCJ137442 deleted the Feat_Console_in_WebSocket_server branch October 30, 2023 09:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants