Skip to content

Conversation

Copy link

Copilot AI commented Sep 28, 2025

This PR introduces a WebSocket adapter interface to decouple go-vncproxy from any specific WebSocket library, enabling support for multiple WebSocket implementations while maintaining full backward compatibility.

Problem

Previously, go-vncproxy was tightly coupled to golang.org/x/net/websocket, making it difficult for users to integrate with other popular WebSocket libraries like github.com/gorilla/websocket or github.com/coder/websocket.

Solution

WebSocket Adapter Interface

Introduced two key interfaces:

type WebSocketAdapter interface {
    Read(p []byte) (n int, err error)
    Write(p []byte) (n int, err error)
    Close() error
    RemoteAddr() string
    Request() *http.Request
    SetBinaryMode() error
}

type WebSocketUpgrader interface {
    Upgrade(w http.ResponseWriter, r *http.Request) (WebSocketAdapter, error)
}

Backward Compatibility

All existing code continues to work unchanged:

// This still works exactly as before
vncProxy := vncproxy.New(&vncproxy.Config{...})
r.GET("/ws", func(ctx *gin.Context) {
    h := websocket.Handler(vncProxy.ServeWS)
    h.ServeHTTP(ctx.Writer, ctx.Request)
})

New Extensible API

Users can now easily integrate custom WebSocket libraries:

// Using the new adapter interface
vncProxy := vncproxy.New(&vncproxy.Config{
    WebSocketAdapter: customUpgrader, // Any WebSocket library
})

r.GET("/ws", func(ctx *gin.Context) {
    handler := vncProxy.HTTPHandler()
    handler.ServeHTTP(ctx.Writer, ctx.Request)
})

Custom Adapter Support

The PR includes documentation and examples for implementing custom adapters, such as for Gorilla WebSocket:

type GorillaWebSocketAdapter struct {
    conn *websocket.Conn
    request *http.Request
}

func (a *GorillaWebSocketAdapter) Read(p []byte) (n int, err error) {
    _, data, err := a.conn.ReadMessage()
    if err != nil {
        return 0, err
    }
    return copy(p, data), nil
}
// ... implement other interface methods

Changes Made

  • New files:

    • websocket_adapter.go: Core interface definitions
    • net_websocket_adapter.go: Default adapter for golang.org/x/net/websocket
    • websocket_adapter_test.go: Comprehensive test suite
    • example_gorilla_adapter.go: Example adapter implementation
  • Modified files:

    • proxy.go: Added adapter support while preserving existing API
    • peer.go: Updated to use WebSocketAdapter interface
    • example/main.go: Enhanced with usage examples
    • README.md: Comprehensive documentation with examples

Benefits

  1. 🔌 Library Independence: Support for any WebSocket library
  2. 🔄 Zero Breaking Changes: Complete backward compatibility
  3. 📦 Batteries Included: Default implementation using existing library
  4. 🎯 Minimal Footprint: Surgical changes with maximum extensibility
  5. 📚 Well Documented: Clear examples for custom implementations

Testing

Added comprehensive tests including:

  • Mock WebSocket adapter implementation
  • Integration tests with the default adapter
  • Interface compliance verification

All existing tests continue to pass, ensuring no regressions.

This change significantly improves the library's flexibility and extensibility while maintaining its simplicity and backward compatibility.

Original prompt

This section details on the original issue you should resolve

<issue_title>Abstract a WebSocket adapter interface to support multiple libraries</issue_title>
<issue_description>To improve compatibility with different WebSocket libraries, introduce an abstraction layer via a WebSocket adapter interface. Provide a default implementation using golang.org/x/net/websocket and allow custom adapters for libraries such as github.com/coder/websocket and github.com/gorilla/websocket.

Proposed approach:

  • Define a unified WebSocketAdapter interface that covers connect/upgrade, read, write, close, and error handling, including binary/text frames and context cancellation.
  • Implement the default adapter based on golang.org/x/net/websocket.
  • Expose clear extension points so users can implement adapters for other libraries (e.g., coder/websocket, gorilla/websocket).
  • Document how to implement and plug in a custom adapter.

This change increases extensibility and decouples go-vncproxy from any specific WebSocket library.</issue_description>

<agent_instructions>implement this</agent_instructions>

Comments on the Issue (you are @copilot in this section)

Fixes #37

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits September 28, 2025 16:25
Co-authored-by: evangwt <3397805+evangwt@users.noreply.github.com>
Co-authored-by: evangwt <3397805+evangwt@users.noreply.github.com>
Copilot AI changed the title [WIP] Abstract a WebSocket adapter interface to support multiple libraries Abstract WebSocket adapter interface to support multiple libraries Sep 28, 2025
Copilot AI requested a review from evangwt September 28, 2025 16:27
@evangwt evangwt marked this pull request as ready for review September 28, 2025 16:50
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.

Abstract a WebSocket adapter interface to support multiple libraries

2 participants