简体   繁体   中英

How to write a simple chat, without a database on meteor.js and react.js?

I want to write a simple chat on meteor.js and thus I do not want to store the data in the database . But I never found how to make an application without a database .

Here is an example of code as I can imagine. Server code:

export let ws = [{_id:'1', text:'test1'}, {_id:'2', text:'test2'}];
Meteor.publish('ws', function wsPub() { return ws; });
let ctr = 3;
Meteor.methods({
    'addMsg'(text) {  ws.push({_id:ctr+1, text:text});  }
});

and client code:

import {ws} from '../api/model.js';

class Rtc extends Component {
  constructor(props) {
    super(props);
  }
  addMsg(e){
    e.preventDefault();
    Meteor.call('addMsg', this.refs.input.value);
  }
  render() {
    return (
      <div>
         {this.props.ws.map((item, i)=>{ 
           return(<span key={i._id}>{item.text}</span>); 
         })}
         <input type="text" ref="input" />
         <input type="submit" value="submit" onClick={this.addMsg.bind(this)}/>
       </div>
    );
  }
}
export default createContainer( () => {
  Meteor.subscribe('ws');
  return { ws: ws };
}, Rtc);

but I do not understand what I wrote is not so in the createContainer ?

UPD: I updated server code, but still websockets does not work:

Meteor.publish('ws', function wsPub() {
  let self = this;
  ws.forEach( (msg)=> {
    self.added( "msg", msg._id, msg.text );
  });
  self.ready();
  // return ws;
});

What you suppose won't work. Because Meteor.publish returns a cursor to a Collection or array of Collections . According to the official documentation :

Publish functions can return a Collection.Cursor, in which case Meteor will publish that cursor's documents to each subscribed client. You can also return an array of Collection.Cursors, in which case Meteor will publish all of the cursors.

Again, when you subscribe to a publication, it stores the data(as cursor to the same collection as the publication) locally in MiniMongo . So a chat without database is not technically possible with pub-sub in Meteor.

If you want to control what is sent over a publish, get a reference to the "publish instance" (really a specific client with a specific subscription) and use its add / change / remove commands:

let messages = [];
let clients = [];
Meteor.publish('ws', function() {
    clients.push(this);
    _.each(messages, (message) => {this.added('msg', message._id, message);});
    this.ready();
});
Meteor.methods({
    addMsg(text) {
        let newMessage = {_id: Meteor.uuid(), text: text};
        messages.push(newMessage);
        _.each(clients, (client) => {client.added('msg', newMessage._id, newMessage);});
    }
});

Regarding your code that you wrote in an update: you're sending a string where the function added expects a document (an object ). Also, unlike this example above, you do not tell the clients when the ws (messages array) has changed.

I'd recommend also renaming these things to be more verbose and clear :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM