在client和serviceWorker之间传输数据

2024-04-05

我想尝试在 serviceWorker 中运行 websockets。

我编写了注册serviceWorker的代码:

if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register(
            GetDataForUser.settings.service_worker + "?version=" + GetDataForUser.settings.service_worker_version,
            {scope: './'}
        )
        .then(() => navigator.serviceWorker
            .ready
            .then((worker) => {
        console.log(worker);
                worker.sync.register('syncdata');
            })
        )
        .catch((err) => console.log(err));
    navigator.serviceWorker.addEventListener('message', event => {
        console.log('++++++++++++++++++++', event.data.msg, event.data.url);
    });
}

并编写serviceWorker代码:

var ws = null;

self.addEventListener('install', (event) => {
    console.log('Install');
});

self.addEventListener('activate', (event) => {
    console.log('Activate');

    ws = new WebSocket('ws://local.ll:8880');

    ws.onopen = function() {
        console.log("Open");
    };

    // On message receive
    ws.onmessage = function (event) {
        console.log("Message receive " + event.data);
        console.log(event);
        event.ports[0].postMessage({'test': 'This is my response.'});
    };

    // On error connection
    ws.onerror = function (error) {
        console.log("Error " + error.message);
    };

    // On close connection
    ws.onclose = function (event) {
        if (event.wasClean) {
            console.log('clean closed');

        } else {
            console.log('broken connection');
        }
        console.log('Code: ' + event.code + ' reason: ' + event.reason);
    };
});

self.addEventListener('fetch', (event) => {});

self.addEventListener('message', function (evt) {
    console.log('postMessage received', evt.data);
    ws.send('121212');
});

接下来我尝试将数据发送到 serviceWorker:

navigator.serviceWorker.controller.postMessage({'hello': 'world'});

但收到错误:

Uncaught TypeError: Cannot read property 'postMessage' of null

console.log(navigator.serviceWorker);
ServiceWorkerContainer {controller: null, ready: Promise, oncontrollerchange: null, onmessage: null}

接下来尝试从 serviceWorker 向客户端发送消息:

event.ports[0].postMessage({'test': 'This is my response.'});

但 event.ports 是空的。

怎么了? 如何在client和serviceWorker之间传输数据。


要修复控制器为空的错误,您需要添加激活事件侦听器

self.clients.claim()

如果没有这个,当服务工作者被激活时,页面不会被它控制,直到下一次导航。这允许服务工作人员在页面处于活动状态时立即控制页面。

但我不认为这是你唯一的问题。看看你的代码,我认为你混淆了 WebSocket 和 MessageChannel。您似乎尝试使用 WebSocket 在客户端和服务工作人员之间发送消息,而您应该使用 MessageChannel 来发送消息。

例如,如果我们想要从客户端向软件发送消息并允许软件响应这些消息,我们创建一个 MessageChannel,然后将该通道的端口与消息一起发送,以供软件在其响应中使用。 在客户端:

var msg = new MessageChannel();
msg.port1.onmessage = function(event){
    //Response received from SW
    console.log(event.data);
};
// Send message to SW
navigator.serviceWorker.controller.postMessage("hello", [msg_chan.port2]);

在软件中:

self.addEventListener('message', function(event){
    //Message received from client
    console.log(event.data);
    //Send response to client using the port that was sent with the message
    event.ports[0].postMessage("world");
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在client和serviceWorker之间传输数据 的相关文章

  • 使用 vscode 调试器调试 next.js

    我已经使用安装了一个项目创建下一个应用程序 https github com segmentio create next app 我需要使用我的编辑器 vscode 调试服务器端渲染 所以我访问过vscode recipes 如何调试 ne
  • React js Stripe 结账不起作用

    我正在尝试在 React js 应用程序中呈现条带结账默认表单
  • Android 设备上的 PhoneGap 蓝牙插件

    我一直在尝试让 PhoneGap 工作的蓝牙插件 但我似乎不知道哪里出了问题 首先 我的测试设备是 Galaxy S3 GT 19305T 应用程序是使用PhoneGap CLI http docs phonegap com en 3 0
  • 在 Vue.js 中从父组件执行子方法

    目前 我有一个 Vue js 组件 其中包含其他组件的列表 我知道使用 vue 的常见方式是将数据传递给孩子 并从孩子向父母发出事件 但是 在这种情况下 我想在子组件中的按钮出现时执行子组件中的方法 parent被点击 哪种方法最好 一种建
  • 使用 useReducers 调度函数发送多个操作?

    使用时是否可以通过调度函数发送多个动作useReducer挂钩反应 我尝试向它传递一组操作 但这会引发未处理的运行时异常 明确地说 通常会有一个初始状态对象和一个减速器 如下所示 const initialState message1 nu
  • 使用 jQuery/JS 打开时使
    标签的内容具有动画效果

    我只想要 HTML5 的内容details标记为 滑行 动画打开 而不是仅仅弹出打开 立即出现 这可以用 jQuery Javascript 实现吗 Fiddle http jsfiddle net 9h4Hq HTML
  • 如何监听 jQuery AJAX 请求?

    以下两种实现 ajaxRequest 1 2 的方法应该是等效的 话说回来 为什么验证回调已执行的单元测试 3 在 1 中成功而在 2 中失败 我应该如何重写测试 3 来监视 2 中的成功回调 如果我尝试stub jQuery ajax使用
  • 可以使用 jQuery 或 Javascript 将图片的特定部分用作链接吗?

    我有这个想法 将图片 而不是文本 的各个部分链接到不同的页面或网站 并且我想在不实际创建不同的照片并将它们彼此靠近的情况下完成 这样看起来就像是一张完整的图片 这里有人知道如何使用 JavaScript 的变体 例如 jQuery 或纯 J
  • Javascript正则表达式用于字母字符和空格? [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我需要一个
  • 从未用 @flow 标记的导入文件中获取类型定义

    TL DR我怎么告诉flow从未声明的导入模块导入类型定义 flow 加长版 流接缝能够从不使用流语法的文件中派生类型 请参阅示例 示例文件 flow js if Math random lt 0 5 var y hello else va
  • JavaScript 重定向到新窗口

    我有以下代码 它根据下拉列表的值重定向到页面 我如何使其在新窗口中打开 function goto form var index form select selectedIndex if form select options index
  • Jquery/Javascript 上传和下载文件,无需后端

    是否可以在没有后端服务器的情况下在 JavaScript 函数中下载和上传文件 我需要导出和导入由 JavaScript 函数生成的 XML 我想创建按钮 保存 xml 来保存文件 但我不知道是否可行 另一方面 我希望将 XML 文件直接上
  • Meteor - 从客户端取消服务器方法

    我正在通过服务器方法执行数据库计数 用户可以选择他们希望如何执行计数 然后调用该方法 我的问题是 计数可能需要一些时间 并且用户可能会在方法运行时改变主意并请求不同的计数 有什么方法可以取消调用的方法并运行新的计数吗 我认为 this un
  • 跟踪用户何时点击浏览器上的后退按钮

    是否可以检测用户何时单击浏览器的后退按钮 我有一个 Ajax 应用程序 如果我可以检测到用户何时单击后退按钮 我可以显示适当的数据 任何使用 PHP JavaScript 的解决方案都是优选的 任何语言的解决方案都可以 只需要我可以翻译成
  • 在 webpack 2.x 中使用 autoprefixer 和 postcss

    如何使用autoprefixer使用 webpack 2 x 以前 它曾经是这样的 module loaders test scss loader style css sass postcss postcss gt return autop
  • 如何使输入字段和提交按钮变灰

    我想变灰这两件事 http doorsplit heroku com 歌曲输入字段和提交按钮 直到用户输入艺术家 有没有一种简单的方法可以通过 JQuery 来做到这一点 艺术家输入字段的id是 request artist 你可以这样做
  • 如何获取给定 DOM 元素的所有定义的 CSS 选择器?

    如何使用 jQuery 获取给定 DOM 元素的所有定义的 CSS 选择器 定义后 我的意思是在应用于任何样式表的所有 CSS 选择器document 在某种程度上 这类似于 FireBug 实现的功能 其中显示所选 DOM 元素的所有应用
  • Javascript转换时区问题

    我在转换当前时区的日期时间时遇到问题 我从服务器收到此日期字符串 格式为 2015 10 09T08 00 00 这是中部时间 但是当我使用 GMT 5 中的 new Date strDate 转换此日期时间时 它返回给我的信息如下 这是不
  • 条件在反应本机生产中失败,但在开发中有效

    我创建了一个反应本机应用程序 我需要通过它进行比较 如果属实 就会执行死刑 问题是 该条件适用于 React Native 开发模式 而不适用于 React Native 生产版本 我使用 firebase 作为数据库 也使用 redux
  • 如何在 pg-promise 中设置模式

    我正在搜索的文档pg 承诺 https github com vitaly t pg promise特别是在创建客户端时 但我无法找到设置连接中使用的默认架构的选项 它始终使用public架构 我该如何设置 通常 为数据库或角色设置默认架构

随机推荐