# Push Notifications vs Polling in LINEJS: Real-Time Event Handling

> Discover the difference between push notifications and polling in LINEJS. Learn how push notifications stream events instantly via TCP/HTTP-2, while polling uses fixed timers for event fetching.

- Repository: [Evex  Developers/linejs](https://github.com/evex-dev/linejs)
- Tags: deep-dive
- Published: 2026-03-01

---

**Push notifications in LINEJS use a persistent TCP/HTTP-2 connection to stream events instantly from the server, while polling repeatedly calls HTTP APIs on a fixed timer to fetch batches of events.**

The evex-dev/linejs library provides two distinct mechanisms for receiving Talk and Square events. Understanding the difference between push notifications and polling in LINEJS is essential for building efficient applications that minimize latency and server load. The source code clearly delineates these approaches across separate architectural layers.

## How Push Notifications Work in LINEJS

Push notifications establish a long-lived connection that allows the LINE server to deliver events as they occur.

### The Persistent Connection Architecture

In [`packages/linejs/base/push/connManager.ts`](https://github.com/evex-dev/linejs/blob/main/packages/linejs/base/push/connManager.ts), the `initializeConn()` method opens a single socket to the `/PUSH/1/subs?m=${m}` endpoint. The parameter `m` encodes the requested services: **Talk = 5** and **Square = 3**. This connection remains open indefinitely, enabling the server to push event frames down to the client immediately upon generation without repeated handshakes.

### Stream-Based Event Consumption

The client wraps incoming frames in **ReadableStream** instances (`opStream` for Talk operations, `sqStream` for Square events). You consume these using standard async iteration. The `_OnPushResponse()` function in [`connManager.ts`](https://github.com/evex-dev/linejs/blob/main/connManager.ts) parses each frame and dispatches it to the appropriate stream writer.

## How Polling Works in LINEJS (Deprecated)

Polling represents the legacy approach and is explicitly marked as deprecated in the source code.

### Timer-Based HTTP Requests

Located in [`packages/linejs/base/polling/mod.ts`](https://github.com/evex-dev/linejs/blob/main/packages/linejs/base/polling/mod.ts), the private async generators `_listenTalkEvents()` and `_listenSquareEvents()` implement the polling strategy. These generators repeatedly call standard HTTP service methods—`client.talk.sync()` and `client.square.fetchMyEvents()`—followed by `await sleep(pollingInterval)`. The default intervals are **100 ms for Talk** and **1000 ms for Square**.

Unlike push, polling maintains no persistent connection. Each iteration opens a new HTTP request, returns accumulated events, then pauses until the next timer tick, creating higher latency and bandwidth overhead.

## Key Differences: Push vs Polling

| Feature | Push Notifications | Polling (Deprecated) |
|---------|-------------------|---------------------|
| **Connection** | Single persistent TCP/HTTP-2 socket to `/PUSH` | Repeated HTTP connections |
| **Latency** | Real-time delivery | Delayed by polling interval |
| **Resource Usage** | Lower bandwidth, one connection | Higher overhead per request |
| **Entry Point** | `client.poll.listenTalkEvents()` | `client.createPolling().listenTalkEvents()` |
| **Implementation** | `ConnManager.initializeConn()`, `_OnPushResponse()` | Private generators `_listenTalkEvents()`, `_listenSquareEvents()` |
| **Status** | Recommended default | Deprecated, backward compatibility only |

## Code Examples

### Receiving Talk Events via Push (Recommended)

The push approach uses `client.poll`, which internally initializes the connection via `initLegyPusher()` and returns a `ReadableStream`.

```ts
import { Client } from "@evex/linejs";

async function main() {
  const client = new Client({
    device: "iOS",
    version: "14.0",
  });
  await client.login();

  // Returns a ReadableStream backed by the push connection
  const talkStream = client.poll.listenTalkEvents();

  for await (const op of talkStream) {
    console.log("Talk operation:", op);
  }
}
main();

```

*Execution path*: `listenTalkEvents()` → `initLegyPusher()` → `ConnManager.initializeConn()` → `opStream` writer enqueue.

### Receiving Events via Deprecated Polling

Use `createPolling()` to instantiate a fresh polling instance. This invokes the private `_listenTalkEvents()` generator.

```ts
import { Client } from "@evex/linejs";

async function main() {
  const client = new Client({ device: "iOS" });
  await client.login();

  const polling = client.createPolling();
  
  // Uses the deprecated polling generator
  for await (const op of polling.listenTalkEvents()) {
    console.log("Polled operation:", op);
  }
}
main();

```

*Execution path*: `_listenTalkEvents()` → `client.talk.sync()` → `sleep(pollingInterval)` → loop.

## Summary

- **Push notifications** in LINEJS use a persistent `/PUSH` connection via `ConnManager` to stream events in real-time through `ReadableStream` interfaces (`opStream`, `sqStream`).
- **Polling** repeatedly calls `talk.sync()` and `square.fetchMyEvents()` with fixed delays (100ms/1000ms), consuming more bandwidth and introducing latency.
- The push implementation resides in [`packages/linejs/base/push/connManager.ts`](https://github.com/evex-dev/linejs/blob/main/packages/linejs/base/push/connManager.ts) and is accessed through `client.poll.listenTalkEvents()`.
- **Polling** generators in [`packages/linejs/base/polling/mod.ts`](https://github.com/evex-dev/linejs/blob/main/packages/linejs/base/polling/mod.ts) are marked `@deprecated` and should only be used when persistent connections are impossible.
- Push is the default for new applications; polling remains available solely for backward compatibility in restricted network environments.

## Frequently Asked Questions

### What is the primary technical difference between push and polling in LINEJS?

Push maintains a single long-lived TCP/HTTP-2 connection to the `/PUSH` endpoint where the server streams events immediately, while polling opens new HTTP connections repeatedly on a timer to fetch batched events. According to the evex-dev/linejs source, push uses `ConnManager.initializeConn()` for the persistent socket, whereas polling uses private async generators with `sleep()` delays.

### Why is polling marked as deprecated in the LINEJS codebase?

Polling is deprecated because it creates unnecessary server load through repeated HTTP handshakes and introduces latency based on the polling interval. The push implementation delivers events instantly and conserves bandwidth, making it the superior architecture for real-time applications.

### How do I switch from polling to push notifications in my LINEJS application?

Replace `client.createPolling().listenTalkEvents()` with `client.poll.listenTalkEvents()`. The `client.poll` property automatically initializes the push connection via `initLegyPusher()` and returns `ReadableStream` instances that you consume with `for await...of` loops. No additional configuration is required beyond standard client initialization.

### Can I use both push notifications and polling simultaneously?

While technically possible by creating separate instances, it is not recommended. The `ConnManager` handles event deduplication and connection state; running both methods simultaneously against the same account could cause event processing conflicts and increase server load unnecessarily.