Push Notifications vs Polling in LINEJS: Real-Time Event Handling
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, 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 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, 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.
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.
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
/PUSHconnection viaConnManagerto stream events in real-time throughReadableStreaminterfaces (opStream,sqStream). - Polling repeatedly calls
talk.sync()andsquare.fetchMyEvents()with fixed delays (100ms/1000ms), consuming more bandwidth and introducing latency. - The push implementation resides in
packages/linejs/base/push/connManager.tsand is accessed throughclient.poll.listenTalkEvents(). - Polling generators in
packages/linejs/base/polling/mod.tsare marked@deprecatedand 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →