sw-stream

Posted wanghui-garcia

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sw-stream相关的知识,希望对你有一定的参考价值。

https://github.com/kumavis/sw-stream

ServiceWorkerStream and ServiceWorkerGlobalListener

This a utility for creating streams between the page and a servive worker.

在页面也服务器中创建流

usage

in page

pass the registered service worker to create a duplex stream.

传递一个登录的service worker去创建一个双工流

const duplex = SwStream({ serviceWorker: this.serviceWorker.controller })
 

There is an optional context property that will be passed along on the initial handshake and retreivable from the messageEvent.data.context received from the SwGlobalListener.

context参数是可选的,它将会在第一次握手时传递并且会被从SwGlobalListener检索得到的messageEvent.data.context检索到

const duplex = SwStream({ serviceWorker, context })
 
in ServiceWorker

listen for client connections

const connectionListener = new SwGlobalListener(self)

connectionListener.on(remote, (portStream, messageEvent) => {
  // ...
})

 

 

看测试了解使用:

sw-stream/test/service-worker.js (即background.js)

const SwGlobalListener = require(../lib/sw-global-listener)
const swGlobal = self

// setup ServiceWorkerGlobal and capture clients

swGlobal.addEventListener(activate, function(event) {
  event.waitUntil(swGlobal.clients.claim())
})

swGlobal.oninstall = function (event) {
  event.waitUntil(swGlobal.skipWaiting())
}

// listen for clients

const connectionListener = new SwGlobalListener(swGlobal)

connectionListener.on(remote, (portStream, messageEvent) => {
  console.log(got a remote connection!)
  remoteStream.on(data, (message) => {
    console.log(message:, message)
    // example: double value and then send back
    let newValue = message.value * 2
    remoteStream.write({ value: newValue })
  })
})

 

sw-stream/lib/sw-global-listener.js

const EventEmitter = require(events)
const PortStream = require(./message-channel-port-stream)


class SwGlobalListener extends EventEmitter {

  constructor (swGlobal) {
    super()
    swGlobal.addEventListener(message, (messageEvent) => {
      // validate port
      if (!messageEvent.data) return
      if (messageEvent.data.action !== handshake) return
      // process message
      const port = messageEvent.ports[0]
      if (!port) throw new Error(Handshake missing port...)
      // create new portStream
      const portStream = new PortStream(port)
      // announce new connection
      this.emit(remote, portStream, messageEvent)
    })
  }

}

module.exports = SwGlobalListener

 

sw-stream/lib/message-channel-port-stream.js

const Duplex = require(readable-stream).Duplex
const inherits = require(util).inherits

module.exports = MessageChannelPortDuplexStream


inherits(MessageChannelPortDuplexStream, Duplex)

function MessageChannelPortDuplexStream (port) {
  Duplex.call(this, {
    objectMode: true,
  })
  this._port = port
  port.onmessage = this._onMessage.bind(this)
}

// private

MessageChannelPortDuplexStream.prototype._onMessage = function (event) {
  const msg = event.data
  if (Buffer.isBuffer(msg)) {
    delete msg._isBuffer
    var data = new Buffer(msg)
    this.push(data)
  } else {
    this.push(msg)
  }
}

// stream plumbing

MessageChannelPortDuplexStream.prototype._read = noop

MessageChannelPortDuplexStream.prototype._write = function (msg, encoding, cb) {
  try {
    if (Buffer.isBuffer(msg)) {
      var data = msg.toJSON()
      data._isBuffer = true
      this._port.postMessage(data)
    } else {
      this._port.postMessage(msg)
    }
  } catch (err) {
    return cb(new Error(MessageChannelPortDuplexStream - disconnected))
  }
  cb()
}

// util

function noop () {}

 

 

sw-stream/test/sw-launcher.js

const EventEmitter = require(events)
const SwStream = require(../lib/sw-stream)


module.exports = class ServiceWorkerLauncher extends EventEmitter {
  constructor (opts) {
    super()
    this.serviceWorker = navigator.serviceWorker
    this.startWorker()
    .then(registeredWorker => {
      console.log(setting up stream...)
      const duplex = SwStream(registeredWorker)
      duplex.on(data, (chunk) => {console.log(controller saw:, chunk) })
      duplex.on(error, (chunk) => {console.log(controller saw:, chunk) })
      duplex.write({ value: 42 })
    })
    .catch(err => {
      this.handleError(err)
    })
  }

  startWorker () {
    // check to see if their is a preregistered service worker
    if (!this.serviceWorker.controller) {
      console.log(registering...)
      return Promise.resolve(this.registerWorker())
    } else {
      console.log(ready)
      return Promise.resolve(this.serviceWorker.ready)
    }
  }

  registerWorker () {
    return this.serviceWorker.register(sw-bundle.js)
    .then(sw => {
      return sw
    })
  }

  handleError (err, contextMessage) {
    if (!err) {
      console.error(contextMessage)
      this.emit(error, contextMessage)
    } else {
      console.error(err)
      this.emit(error, err)
    }
  }
}

 

sw-stream/lib/sw-stream.js

const PortStream = require(./message-channel-port-stream)

module.exports = SericeWorkerStream


function SericeWorkerStream({ serviceWorker, context }) {
  // create message channel for communication
  const messageChannel = new MessageChannel()
  // send handshake including port to respond on
  serviceWorker.postMessage({ action: handshake, context }, [messageChannel.port2])
  // construct stream around local message channel port
  const portStream = new PortStream(messageChannel.port1)
  return portStream
}

 

 

 

 












以上是关于sw-stream的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序代码片段

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器