Add named pipe support for Windows
This PR applies the suggestions from #1808 to add support to the client for named pipes on Windows.
Cross Platform Example
This example works on both MacOS and Windows.
// paths.js
import * as os from 'os'
import { join } from 'path'
let sockPath = join(os.tmpdir(), `ws.example.sock`)
if (os.platform() === 'win32') {
sockPath = join('\\\\.\\pipe', sockPath)
console.log('updated sockPath', sockPath)
}
export const sockUrl = `ws+unix:///${sockPath}`
export { sockPath }
// server.js
import { existsSync, unlinkSync } from 'fs'
import { createServer } from 'http'
import * as os from 'os'
import { WebSocketServer } from 'ws'
import { sockPath } from './paths.js'
const server = createServer()
const wss = new WebSocketServer({ server })
wss.on('connection', function connection(ws) {
console.log('server connected')
ws.on('message', (data) => {
console.log('data from client', data.toString())
})
ws.send('hello')
})
// server.listen() throws if unix domain socket exists
if (os.platform() !== 'win32' && existsSync(sockPath)) {
unlinkSync(sockPath)
}
server.listen(sockPath)
// client.js
import { WebSocket } from 'ws'
import { sockUrl } from './paths.js'
const ws = new WebSocket(sockUrl)
ws.on('open', () => {
console.log('client socket open')
ws.send('hello')
})
The problem with Windows named pipes is that they create ambiguity when used in URLs. The pipe name string specified by PipeName in \\.pipe\PipeName can include any character other than a backslash.
For example the pipe name string in \\.\pipe\foo:/bar?bar=baz is foo:/bar?bar=baz but when added to a URL the ?bar=baz part is parsed as the URL search component. Similarly the : character creates ambiguity because it cannot be used as the actual request path separator. The same applies to :/.
The feature can only be added with limitations so I think it's not worth it.
Closing in favor of #2079