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

allow public access to socket and keep it open when requested #471

Open
wants to merge 1 commit into
base: stable
Choose a base branch
from

Conversation

Bersaelor
Copy link

Hey there, I've been using swifter for a while, but in my case I was always keeping the sockets open, to allow for stateful connections.
In my case communication is bidirectional, the phone acts as a sort of remote for the browser window.

The below are all the changes I needed from this project, would this be something worth merging into the main branch?

@michaelenger
Copy link
Contributor

michaelenger commented Sep 28, 2021

Hey @Bersaelor, could you give me an example of how you're using this?

Also, could you fix the merge conflict while you're at it?

@michaelenger michaelenger self-assigned this Sep 28, 2021
@Bersaelor
Copy link
Author

Bersaelor commented Sep 29, 2021

hey @michaelenger ,

from a UX perspective the user only opens the page in their browser and then never interacts with the desktop pc/mac anymore, instead going across the room and controlling the website with their phone.

First I save the socket that is currently open when the website loads, like this:

    // during init
            do {
            try httpServer.start()
        }
        catch {
            log.error("While starting httpserver: \(error)")
        }
        
        httpServer["/"] = htmlHandler(filePathComponent: "/Web/index.html", context: rootContext)
        httpServer["/websocket-echo"] = websocket(
            text: webSocket(session:text:),
            binary: nil, pong: nil, connected: nil, disconnected: nil
        )
    }
  
    fileprivate func webSocket(session: WebSocketSession, text: String) {
        guard text.hasPrefix("BTI$") else {
            // if text doesn't start with 'Browser To Iphone', then it's not a socket message
            session.writeText(text)
            return
        }
        
        log.debug("message: \(text)")

        if self.currentSocket == nil {
            self.socketDidOpen()
            currentSocket = session.socket
            session.socket.didClose = { [weak self] in
                self?.socketDidClose()
                self?.currentSocket = nil
            }
        }
        
        guard let message = RemoteScreenMessage(message: text) else {
            log.error("text couldn't be parsed: \( text )")
            return
        }
        
        log.debug("Message: \(message)")
        
        DispatchQueue.main.async {
            self.received(message)
        }
    }

and then when I want to make the currently presented desktop page change I do:

    fileprivate func sendToClient(_ message: MessageToBrowser) {
        let msgString = "....."
        
        log.debug("Attempting to send msg: \(msgString)")
        
        networkingQueue.async {
            guard let socket = self.currentSocket else { return }
            let session = WebSocketSession(socket)
            session.shouldCloseSocket = false
            if message.type.shouldBeRepeated { self.lastMessage = message }
            session.writeText(msgString)
        }
    }

@michaelenger
Copy link
Contributor

This is a cool idea, what do you think @Vkt0r?

@michaelenger michaelenger removed their assignment Jun 14, 2023
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.

3 participants