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

Dependencies, Workflow, Documentation #38

Merged
merged 10 commits into from
Feb 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
name: Pull Request
about: Pull Request
title: ''
labels: ''
assignees: ''
---

Thanks for contributing!

Before you create a Pull Request, make sure to read the [Contributing](../../docs/Contributing.md) specification.
16 changes: 8 additions & 8 deletions .github/workflows/acceptance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
name: Unit test
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
Expand All @@ -24,7 +24,7 @@ jobs:
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache dependencies
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
Expand All @@ -39,19 +39,19 @@ jobs:
name: Code standard
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.2"
php-version: "8.3"
coverage: none
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache dependencies
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
Expand All @@ -66,19 +66,19 @@ jobs:
name: Code coverage
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.2"
php-version: "8.3"
coverage: xdebug
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache dependencies
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.0",
"phpunit/phpunit": "^9.0 | ^10.0",
"phpunit/phpunit": "^9.0 | ^10.0 | ^11.0",
"phrity/net-mock": "1.3",
"squizlabs/php_codesniffer": "^3.5"
}
Expand Down
15 changes: 14 additions & 1 deletion docs/Changelog.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
[Documentation](Index.md) > Changelog
[Documentation](Index.md) / Changelog

# Websocket: Changelog

## `v2.2`

> PHP version `^8.0`

### `2.2.0`

* Documentation review (@sirn-se)
* Dependency updates (@sirn-se)

## `v2.1`

> PHP version `^8.0`

### `2.1.2`

* Allow repeated headers when pulling HTTP messages (@sirn-se)

### `2.1.1`

* Fix issue with falsy but valid HTTP headers (@axklim)
Expand Down
2 changes: 1 addition & 1 deletion docs/Client.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[Documentation](Index.md) > Client
[Documentation](Index.md) / Client

# Websocket: Client

Expand Down
14 changes: 11 additions & 3 deletions docs/Contributing.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
[Documentation](Index.md) > Contributing
[Documentation](Index.md) / Contributing

# Websocket: Contributing

Everyone is welcome to help out!
But to keep this project sustainable, please ensure your contribution respects the requirements below.

## PR Requirements
## Pull Request requirements

Requirements on pull requests;
* All tests **MUST** pass.
* Code coverage **MUST** remain at 100%.
* Code **MUST** adhere to PSR-1 and PSR-12 code standards.

## SemVer, versions, and target branches

This repo uses strict [Semantic Versioning](https://semver.org).

* MAJOR version when introducing breaking changes
* MINOR version when adding features
* PATCH version when fixing bugs and equivalent changes

Base your patch on corresponding version branch, and target that version branch in your pull request.

| Version | Branch | PHP | Status |
| --- | --- | --- | --- |
| [`2.2`](https://github.com/sirn-se/websocket-php/tree/2.2.0) | `v2.2-main` | `^8.1` | Future version |
| [`2.1`](https://github.com/sirn-se/websocket-php/tree/2.1.0) | `v2.1-main` | `^8.0` | Current version |
| [`2.0`](https://github.com/sirn-se/websocket-php/tree/2.0.0) | `v2.0-main` | `^8.0` | Bug fixes only |
| [`1.7`](https://github.com/sirn-se/websocket-php/tree/1.7.0) | `v1.7-master` | `^7.4\|^8.0` | Bug fixes only |
Expand All @@ -27,7 +36,6 @@ Base your patch on corresponding version branch, and target that version branch
| [`1.1`](https://github.com/sirn-se/websocket-php/tree/1.1.0) | - | - | Not supported |
| [`1.0`](https://github.com/sirn-se/websocket-php/tree/1.0.0) | - | - | Not supported |


## Dependency management

Install or update dependencies using [Composer](https://getcomposer.org/).
Expand Down
2 changes: 1 addition & 1 deletion docs/Examples.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[Documentation](Index.md) > Examples
[Documentation](Index.md) / Examples

# Websocket: Examples

Expand Down
1 change: 1 addition & 0 deletions docs/Index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
* [Changelog](Changelog.md) - The changelog of this repo
* [Contributing](Contributing.md) - Contributors and requirements
* [Examples](Examples.md) - Examples
* [License](../LICENCE.md) - License
2 changes: 1 addition & 1 deletion docs/Listener.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[Documentation](Index.md) > Listener
[Documentation](Index.md) / Listener

# Websocket: Listener

Expand Down
2 changes: 1 addition & 1 deletion docs/Message.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[Documentation](Index.md) > Message
[Documentation](Index.md) / Message

# Websocket: Message

Expand Down
171 changes: 9 additions & 162 deletions docs/Middleware.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[Documentation](Index.md) > Middleware
[Documentation](Index.md) / Middleware

# Websocket: Middleware

Expand All @@ -24,172 +24,19 @@ $server
These two middlewares provide standard operability according to WebSocket protocol,
and should be added unless you write your own implementation of close and ping/pong handling.

* `CloseHandler` - Automatically acts on incoming and outgoing Close requests, as specified in WebSocket protocol
* `PingResponder` - Responds with Pong message when receiving a Ping message, as specified in WebSocket protocol
* [CloseHandler](Middleware/CloseHandler.md) - Automatically acts on incoming and outgoing Close requests, as specified in WebSocket protocol
* [PingResponder](Middleware/PingResponder.md) - Responds with Pong message when receiving a Ping message, as specified in WebSocket protocol

## Optional middlewares

These middlewares are included in library and can be added to provide additional functionality.

* `PingInterval` - Used to automatically send Ping messages at specified interval
* `Callback` - Apply provided callback function on specified actions
* [PingInterval](Middleware/PingInterval.md) - Used to automatically send Ping messages at specified interval
* [Callback](Middleware/Callback.md) - Apply provided callback function on specified actions

## Middleware descriptions
## Creating your own middleware

Description of included middlewares.
You can create your own middleware by implementing relevant interfaces.
A middleware may handle WebSocket message transfers, HTTP handshake operations, and Tick operability.

### The CloseHandler middleware

* When a Close message is received, CloseHandler will respond with a Close confirmation message
* When a Close confirmation message is received, CloseHandler will close the connection
* When a Close message is sent, CloseHandler will block further messages from being sent

```php
$client_or_server->addMiddleware(new WebSocket\Middleware\CloseHandler());
```

### The PingResponder middleware

* When a Ping message is received, PingResponder will respond with a Pong message

```php
$client_or_server->addMiddleware(new WebSocket\Middleware\PingResponder());
```

### The PingInterval middleware

* Sends Ping messages on Connection at interval, typically used as "heartbeat" to keep connection open
* If `interval` is not specified, it will use connection timeout configuration as interval

```php
$client_or_server->addMiddleware(new WebSocket\Middleware\PingInterval(interval: 10));
```

### The Callback middleware

This middleware will apply callback functions on certain actions.

```php
$client_or_server
->addMiddleware(new WebSocket\Middleware\Callback(
incoming: function (WebSocket\Middleware\ProcessStack $stack, WebSocket\Connection $connection): WebSocket\Message\Message {
$message = $stack->handleIncoming(); // Get incoming message from next middleware
$message->setContent("Changed message");
return $message;
},
outgoing: function (WebSocket\Middleware\ProcessStack $stack, WebSocket\Connection $connection, WebSocket\Message\Message $message): WebSocket\Message\Message {
$message->setContent('Changed message');
$message = $stack->handleOutgoing($message); // Forward outgoing message to next middleware
return $message;
},
httpIncoming: function (WebSocket\Middleware\ProcessHttpStack $stack, WebSocket\Connection $connection): WebSocket\Http\Message {
$message = $stack->handleHttpIncoming(); // Get incoming message from next middleware
return $message;
},
httpOutgoing: function (WebSocket\Middleware\ProcessHttpStack $stack, WebSocket\Connection $connection, WebSocket\Http\Message $message): WebSocket\Http\Message {
$message = $stack->handleHttpOutgoing($message); // Forward outgoing message to next middleware
return $message;
},
tick: function (WebSocket\Middleware\ProcessTickStack $stack, WebSocket\Connection $connection): void {
$stack->handleTick(); // Forward tick to next middleware
}
));
```

* The `incoming` and `outgoing` callbacks **MUST** return a [Message](Message.md) instance
* The `httpIncoming` and `httpOutgoing` callbacks **MUST** return a HTTP request/response instance respectively
* The `tick` callback returns nothing

The `handleIncoming`, `handleOutgoing`, `handleHttpIncoming`, `handleHttpOutgoing` and `handleTick` methods will pass initiative further down the middleware stack.

## Writing your own middleware

A middleware **MUST** implement the `MiddlewareInterface`.

```php
interface WebSocket\Middleware\MiddlewareInterface
{
public function __toString(): string;
}
```

A middleware that wants to handle incoming messages **MUST** implement the `ProcessIncomingInterface`.

```php
interface WebSocket\Middleware\ProcessIncomingInterface extends WebSocket\Middleware\MiddlewareInterface
{
public function processIncoming(
WebSocket\Middleware\ProcessStack $stack,
WebSocket\Connection $connection
): WebSocket\Message\Message;
}
```

A middleware that wants to handle outgoing messages **MUST** implement the `ProcessOutgoingInterface`.

```php
interface WebSocket\Middleware\ProcessOutgoingInterface extends WebSocket\Middleware\MiddlewareInterface
{
public function processOutgoing(
WebSocket\Middleware\ProcessStack $stack,
WebSocket\Connection $connection,
WebSocket\Message\Message $message
): WebSocket\Message\Message;
}
```

A middleware that wants to handle incoming HTTP messages **MUST** implement the `ProcessHttpIncomingInterface`.

```php
interface WebSocket\Middleware\ProcessHttpIncomingInterface extends WebSocket\Middleware\MiddlewareInterface
{
public function processHttpIncoming(
WebSocket\Middleware\ProcessHttpStack $stack,
WebSocket\Connection $connection
): WebSocket\Http\Message;
}
```

A middleware that wants to handle outgoing HTTP messages **MUST** implement the `ProcessHttpOutgoingInterface`.

```php
interface WebSocket\Middleware\ProcessHttpOutgoingInterface extends WebSocket\Middleware\MiddlewareInterface
{
public function processHttpOutgoing(
WebSocket\Middleware\ProcessHttpStack $stack,
WebSocket\Connection $connection,
WebSocket\Http\Message $message
): WebSocket\Http\Message;
}
```

A middleware that wants to handle Tick operation **MUST** implement the `ProcessTickInterface`.

```php
interface WebSocket\Middleware\ProcessTickInterface extends WebSocket\Middleware\MiddlewareInterface
{
public function processTick(
WebSocket\Middleware\ProcessTickStack $stack,
WebSocket\Connection $connection
): void;
}
```

The `ProcessStack`, `ProcessHttpStack` and `ProcessTickStack` classes are used to hand over initiative to the next middleware in middleware stack.

```php
// Get the received Message, possibly handled by other middlewares
$message = $stack->handleIncoming();

// Forward the Message to be sent, possibly handled by other middlewares
$message = $stack->handleOutgoing($message);

// Get the received HTTP request/response message, possibly handled by other middlewares
$message = $stack->handleHttpIncoming();

// Forward the HTTP request/response message to be sent, possibly handled by other middlewares
$message = $stack->handleHttpOutgoing($message);

// Forward the Tick operation, possibly handled by other middlewares
$stack->handleTick();
```
* [Creating](Middleware/Creating.md) - How to create a Middleware
Loading