2017-03-05 102 views
3

如何使用socket.io創建實時搜索?我使用RethinkDB + Node + Express + Socket.io + Redux + React,我正在監聽事件(它是使用rethinkdb創建的changefeed),它向我發送了10個項目,並使用反應顯示它們。使用socket.io進行實時搜索

現在我想創建實時搜索,它發送查詢到服務器,在數據庫搜索結果,返回前10個結果,並將其發送給客戶端socket.io

// emit events for changes 

r.table('stackoverflow_questions') 
.changes({ includeInitial: true, squash: true }) 
.limit(10) 
.run(connection) 
.then(changefeedSocketEvents(socket, 'topic')) 

-

// Socket.io events for changefeed 

module.exports = function (socket, entityName) { 
    return function (rows) { 
    rows.each(function (err, row) { 
     if (err) { return console.log(err) } else if (row.new_val && !row.old_val) { 
     socket.emit(entityName + ':insert', row.new_val) 
     } else if (row.new_val && row.old_val) { 
     socket.emit(entityName + ':update', row.new_val) 
     } else if (row.old_val && !row.new_val) { 
     socket.emit(entityName + ':delete', { id: row.old_val.id }) 
     } 
    }) 
    } 
} 

我不知道如何使用socket.io實現這一點,您是否必須爲每個自定義查詢動態創建自定義套接字事件偵聽器? (這聽起來荒謬的我,我想,應該有一個簡單的方法)

+0

使用網絡套接字似乎有點矯枉過正。它最適合接收來自服務器的未經請求的消息。獲得搜索結果不是主動提供,可能更簡單地通過AJAX完成。 –

+0

我使用網絡套接字無論哪種方式...我認爲,有比AJAX請求更快,我想實時更新數據。也許我可以創建rest api,並且只向客戶端發送信息,新數據可用,所以瀏覽器會發送http請求來更新它,但它看起來是一個性能較差的解決方案。 – stpoa

+0

另外我在meteor.js中創建了實時搜索,它使用DDP協議在websockets上工作,它工作得很好,所以我認爲它應該是可行和高效的。 – stpoa

回答

0

我找到了解決方法,這裏是一個最低限度的例子:

// server.js 

const express = require('express') 
const app = express() 
const http = require('http') 
const server = http.Server(app) 
const io = require('socket.io')(server) 

app.use(express.static('client')) 

io.on('connection', function(client){ 
    setInterval(() => io.emit('found', 'dfasdfadsfasdfasdf'), 5000) 
    console.log('connected with socket: ' + client.id) 
client.on('search', function (text) { 
    const data = Math.random() 
    io.emit('found', data + text) 
}) 
client.on('disconnect', function(){}) 
}) 

app.get('/') 

server.listen(3000) 

-

<!- index.html -> 

<!DOCTYPE html> 
<html> 
<head> 
    <script src="/socket.io/socket.io.js"></script> 
    <script src="./client.js"></script> 
    <title>socket-io-live-search</title> 
</head> 
<body> 
    <div id='search'> 
    <input type ='text' /> 
    </div> 
</body> 
</html> 

-

// client.js 

var socket = io() 

const loaded =() => { 
    const inputEl = document.querySelector('#search input') 
    inputEl.oninput = (e) => socket.emit('search', e.target.value) 
} 

socket.on('found', (data) => console.log('found: ' + data)) 

document.addEventListener('DOMContentLoaded', loaded, false)