@pushx/vue

Vue.js SDK for pushx.pro real-time messaging
Install
npm install @pushx/vue
Latest Version:1.1.0
Vue:3
License:MIT
Last Updated:Sep 11, 2026
Links: npm
Maintainer: dudoroff

PushX Vue SDK

Реактивный Vue.js SDK для работы с pushx.pro WebSocket сервером.

npm version npm downloads license

Установка

npm / yarn / pnpm

npm install @pushx/vue

# или
yarn add @pushx/vue

# или
pnpm add @pushx/vue

CDN

<!-- Последняя версия -->
<script src="https://unpkg.com/@pushx/vue"></script>

<!-- Конкретная версия -->
<script src="https://unpkg.com/@pushx/vue@1.0.0/dist/pushx-vue.umd.min.js"></script>

<!-- jsDelivr -->
<script src="https://cdn.jsdelivr.net/npm/@pushx/vue"></script>

Быстрый старт

Использование composable

<script setup>
import { usePushX } from '@pushx/vue';

// Создаём экземпляр PushX
const pushx = usePushX({
  appKey: 'your-app-key',
  autoConnect: true, // Автоматическое подключение
});

// Подписка на канал
const channel = pushx.subscribe('my-channel');

// Слушаем события
channel.on('message', (data) => {
  console.log('Получено сообщение:', data);
});

channel.on('notification', (data) => {
  console.log('Уведомление:', data);
});
</script>

<template>
  <div>
    <p>Статус: {{ pushx.connectionState }}</p>
    <p v-if="pushx.socketId">Socket ID: {{ pushx.socketId }}</p>
    <button @click="pushx.connect()" :disabled="pushx.isConnected.value">
      Подключиться
    </button>
    <button @click="pushx.disconnect()" :disabled="!pushx.isConnected.value">
      Отключиться
    </button>
  </div>
</template>

Использование Vue Plugin

// main.js
import { createApp } from 'vue';
import { PushXPlugin } from '@pushx/vue';
import App from './App.vue';

const app = createApp(App);

app.use(PushXPlugin, {
  appKey: 'your-app-key',
  autoConnect: true,
});

app.mount('#app');

Затем в любом компоненте:

<script setup>
import { inject } from 'vue';
import { PushXKey } from '@pushx/vue';

const pushx = inject(PushXKey);

const channel = pushx.subscribe('notifications');
channel.on('new', (data) => {
  console.log('Новое уведомление:', data);
});
</script>

API Reference

usePushX(options)

Основной composable для работы с WebSocket подключением.

Опции
Параметр Тип По умолчанию Описание
appKey string — Ключ приложения PushX (обязательный)
authEndpoint string '/pushx/auth' Эндпоинт для авторизации приватных каналов
autoConnect boolean false Автоматическое подключение при инициализации
reconnectDelay number 1000 Задержка между попытками переподключения (мс)
maxReconnectAttempts number 5 Максимальное количество попыток переподключения
Возвращаемые значения
Реактивное состояние
const pushx = usePushX(options);

// Состояние подключения: 'connecting' | 'connected' | 'disconnected' | 'reconnecting' | 'failed'
pushx.connectionState // Ref<string>

// ID сокета (после подключения)
pushx.socketId // Ref<string | null>

// Ошибка (если есть)
pushx.error // Ref<string | null>

// Количество попыток переподключения
pushx.reconnectAttempts // Ref<number>

// Вычисляемые свойства
pushx.isConnected // ComputedRef<boolean>
pushx.isConnecting // ComputedRef<boolean>
pushx.isReconnecting // ComputedRef<boolean>
Методы
// Подключение к серверу
pushx.connect(options?: { appKey? })

// Отключение
pushx.disconnect()

// Подписка на канал
const channel = pushx.subscribe('channel-name', { 
  signature?: 'pre-signed-signature',
  user?: { id: 1, name: 'User' } // для presence-каналов
})

// Отписка от канала
pushx.unsubscribe('channel-name')

// Получение канала
const channel = pushx.channel('channel-name')

// Получение списка каналов
const channels = pushx.getChannels()
// [{ name, fullName, type, subscribed }]

// Подписка на глобальные события
pushx.on('connected', (data) => console.log('Connected:', data.socketId))
pushx.on('message', (msg) => console.log('Message:', msg))
pushx.on('auth_error', (err) => console.error('Auth error:', err))

// Отписка от событий
pushx.off('connected', handler)

Канал

const channel = pushx.subscribe('my-channel');

// Свойства канала
channel.name        // Полное имя с appKey
channel.originalName // Оригинальное имя
channel.type        // 'public' | 'private' | 'presence'
channel.subscribed  // boolean

// Методы
channel.on('event-name', callback)
channel.off('event-name', callback)
channel.unsubscribe()

Типы каналов

// Публичные каналы (без авторизации)
pushx.subscribe('public-channel')

// Приватные каналы (требуют авторизации через бэкенд)
pushx.subscribe('private-channel')
// SDK автоматически запросит подпись с authEndpoint

// Или можно передать предварительно полученную подпись
pushx.subscribe('private-channel', {
  signature: 'hmac-signature-from-backend'
})

// Presence-каналы (информация о присутствии)
pushx.subscribe('presence-chat', {
  user: {
    id: 123,
    name: 'Иван Петров',
    avatar: 'https://...'
  }
})

Безопасность

⚠️ Важно: Секретный ключ

НИКОГДА не храните секретный ключ в клиентском коде!

Секретный ключ (secret) должен храниться только на вашем бэкенде. Для приватных каналов SDK автоматически запрашивает подпись с вашего бэкенда через authEndpoint.

Схема авторизации приватных каналов

┌─────────────┐    1. subscribe('private-chat')    ┌─────────────────┐
│   Browser   │ ──────────────────────────────────►│  PushX WS     │
│   (SDK)     │                                    │  Server         │
└──────┬──────┘                                    └────────┬────────┘
       │                                                    │
       │ 2. POST /pushx/auth                              │
       │    { channel, socket_id }                          │
       ▼                                                    │
┌─────────────┐    3. Проверка авторизации                  │
│  Ваш        │    + генерация подписи (с secret)           │
│  Backend    │ ───────────────────────────────────────────►│
└─────────────┘    4. signature                             │

Пример бэкенда для авторизации

// Laravel пример
Route::post('/pushx/auth', function (Request $request) {
    $user = auth()->user();
    
    // Проверяем право доступа к каналу
    $channelName = $request->channel_name;
    if (!$user->canAccessChannel($channelName)) {
        return response()->json(['error' => 'Forbidden'], 403);
    }
    
    // Генерируем подпись
    $socketId = $request->socket_id;
    $signature = hash_hmac('sha256', "{$socketId}:{$channelName}", env('PUSHX_SECRET'));
    
    return response()->json(['signature' => $signature]);
});

Кастомные заголовки авторизации

Вы можете передать дополнительные заголовки для запросов авторизации:

// Статические заголовки
const pushx = usePushX({
  appKey: 'your-app-key',
  authEndpoint: '/api/pushx/auth',
  authHeaders: {
    'Authorization': 'Bearer your-token',
    'X-Custom-Header': 'value'
  }
});

// Динамические заголовки (рекомендуется)
const pushx = usePushX({
  appKey: 'your-app-key',
  authEndpoint: '/api/pushx/auth',
  getAuthHeaders: () => ({
    'Authorization': `Bearer ${authStore.token}`
  })
});

При использовании authHeaders или getAuthHeaders SDK не отправляет cookies (credentials: 'include').

Promise-based API

Ожидание подключения

connect() возвращает Promise, который резолвится при успешном подключении:

const pushx = usePushX({ appKey: 'your-app-key' });

// Ожидаем подключения
const { socketId } = await pushx.connect();
console.log('Подключены с socketId:', socketId);

// Теперь можно подписываться на приватные каналы
pushx.subscribe('private-user-123');

Метод waitForConnection()

Для случаев, когда нужно дождаться соединения с таймаутом:

try {
  await pushx.waitForConnection(10000); // 10 секунд
  console.log('Подключены!');
} catch (error) {
  console.error('Не удалось подключиться:', error.message);
}

usePushXChannel(pushx, channelName, options)

Composable для работы с отдельным каналом.

<script setup>
import { usePushX, usePushXChannel } from '@pushx/vue';

const pushx = usePushX({ ... });
const { channel, isSubscribed, events, lastEvent, on, clearEvents } = usePushXChannel(
  pushx,
  'notifications',
  { 
    autoSubscribe: true,
    maxEvents: 50 
  }
);

on('new', (data) => {
  console.log('Новое уведомление:', data);
});
</script>

<template>
  <div>
    <p>Подписан: {{ isSubscribed }}</p>
    <p>Последнее событие: {{ lastEvent }}</p>
    <ul>
      <li v-for="event in events" :key="event.timestamp">
        {{ event.event }}: {{ event.data }}
      </li>
    </ul>
    <button @click="clearEvents">Очистить</button>
  </div>
</template>

Константы

import { ConnectionStates, ChannelTypes } from '@pushx/vue';

// Состояния подключения
ConnectionStates.CONNECTING   // 'connecting'
ConnectionStates.CONNECTED    // 'connected'
ConnectionStates.DISCONNECTED // 'disconnected'
ConnectionStates.RECONNECTING // 'reconnecting'
ConnectionStates.FAILED       // 'failed'

// Типы каналов
ChannelTypes.PUBLIC   // 'public'
ChannelTypes.PRIVATE  // 'private'
ChannelTypes.PRESENCE // 'presence'

Примеры

Чат в реальном времени

<script setup>
import { ref } from 'vue';
import { usePushX } from '@pushx/vue';

const pushx = usePushX({
  appKey: 'chat-app-key',
  autoConnect: true,
});

const messages = ref([]);
const newMessage = ref('');

// Подписка на канал чата
const chatChannel = pushx.subscribe('chat-room-1');

chatChannel.on('message', (data) => {
  messages.value.push(data);
});

chatChannel.on('user_joined', (data) => {
  messages.value.push({
    type: 'system',
    text: `${data.name} присоединился к чату`
  });
});

async function sendMessage() {
  // Отправка через ваш API
  await fetch('/api/chat/send', {
    method: 'POST',
    body: JSON.stringify({
      channel: 'chat-room-1',
      message: newMessage.value
    })
  });
  newMessage.value = '';
}
</script>

Уведомления

<script setup>
import { usePushX } from '@pushx/vue';
import { useNotifications } from './composables/useNotifications';

const pushx = usePushX({ autoConnect: true, ... });
const { show } = useNotifications();

// Приватный канал для уведомлений пользователя
const notificationChannel = pushx.subscribe('private-user-notifications');

notificationChannel.on('new', (data) => {
  show({
    title: data.title,
    message: data.message,
    type: data.type || 'info'
  });
});

notificationChannel.on('badge_update', (data) => {
  // Обновление счётчика непрочитанных
  document.title = data.count > 0 
    ? `(${data.count}) Мой сайт` 
    : 'Мой сайт';
});
</script>

Индикатор набора текста (Typing indicator)

<script setup>
import { ref, computed } from 'vue';
import { usePushX } from '@pushx/vue';

const pushx = usePushX({ ... });
const typingUsers = ref(new Set());

const channel = pushx.subscribe('presence-chat', {
  user: { id: currentUserId, name: currentUserName }
});

channel.on('typing_start', (data) => {
  typingUsers.value.add(data.user_name);
});

channel.on('typing_stop', (data) => {
  typingUsers.value.delete(data.user_name);
});

const typingText = computed(() => {
  const users = Array.from(typingUsers.value);
  if (users.length === 0) return '';
  if (users.length === 1) return `${users[0]} печатает...`;
  if (users.length === 2) return `${users.join(' и ')} печатают...`;
  return `${users.length} человек печатают...`;
});
</script>

Использование через CDN

<!DOCTYPE html>
<html>
<head>
  <title>PushX Vue Example</title>
  <script src="https://unpkg.com/vue@3"></script>
  <script src="https://unpkg.com/@pushx/vue"></script>
</head>
<body>
  <div id="app">
    <p>Status: {{ connectionState }}</p>
    <p v-if="socketId">Socket ID: {{ socketId }}</p>
    <button @click="connect" :disabled="isConnected">Connect</button>
    <button @click="disconnect" :disabled="!isConnected">Disconnect</button>
  </div>

  <script>
    const { createApp } = Vue;
    const { usePushX } = PushXVue;

    createApp({
      setup() {
        const pushx = usePushX({
          appKey: 'your-app-key'
        });

        return {
          connectionState: pushx.connectionState,
          socketId: pushx.socketId,
          isConnected: pushx.isConnected,
          connect: () => pushx.connect(),
          disconnect: () => pushx.disconnect()
        };
      }
    }).mount('#app');
  </script>
</body>
</html>

TypeScript

SDK включает TypeScript определения. Импортируйте типы:

import type { 
  UsePushXReturn, 
  PushXChannel, 
  ChannelInfo,
  ConnectionState,
  ChannelType 
} from '@pushx/vue';

Лицензия

MIT

Related Packages

@priemskiyyy/simulcast-vue

Vue bindings for simulcast: a provider component that owns the realtime session...

606 2
@opentask/taskin-task-provider-pinia

Pinia store for task management integration with Taskin

2,224 1
vue-indiesockets

A lightweight Websocket-Plugin for vue.js including the fitting server implement...

1,545 3
vue-mqtt

Connect to mqtt through websocket, implementation for Vuejs 2

7,696 95
vue-simple-websocket

A simple native reconnecting websocket for Vue.js

1,595 9

Version History

Version Released Vue License
1.1.0 ^3.0.0 MIT