微信小程序WebSocket实现聊天对话功能


Posted in Javascript onJuly 06, 2018

本文实例为大家分享了微信小程序WebSocket实现聊天对话功能的具体代码,供大家参考,具体内容如下

js

var app = getApp();
var socketOpen = false;
var frameBuffer_Data, session, SocketTask;
var url = 'ws://请填写您的长链接接口地址';
var upload_url ='请填写您的图片上传接口地址'
Page({
 data: {
  user_input_text: '',//用户输入文字
  inputValue: '',
  returnValue: '',
  addImg: false,
  //格式示例数据,可为空
  allContentList: [],
  num: 0
 },
 // 页面加载
 onLoad: function () {
  this.bottom();
 },
 onShow: function (e) {
  if (!socketOpen) {
   this.webSocket()
  }
 },
 // 页面加载完成
 onReady: function () {
  var that = this;
  SocketTask.onOpen(res => {
   socketOpen = true;
   console.log('监听 WebSocket 连接打开事件。', res)
  })
  SocketTask.onClose(onClose => {
   console.log('监听 WebSocket 连接关闭事件。', onClose)
   socketOpen = false;
   this.webSocket()
  })
  SocketTask.onError(onError => {
   console.log('监听 WebSocket 错误。错误信息', onError)
   socketOpen = false
  })
  SocketTask.onMessage(onMessage => {
   console.log('监听WebSocket接受到服务器的消息事件。服务器返回的消息', JSON.parse(onMessage.data))
   var onMessage_data = JSON.parse(onMessage.data)
   if (onMessage_data.cmd == 1) {
    that.setData({
     link_list: text
    })
    console.log(text, text instanceof Array)
    // 是否为数组
    if (text instanceof Array) {
     for (var i = 0; i < text.length; i++) {
      text[i]
     }
    } else {
 
    }
    that.data.allContentList.push({ is_ai: true, text: onMessage_data.body });
    that.setData({
     allContentList: that.data.allContentList
    })
    that.bottom()
   }
  })
 },
 webSocket: function () {
  // 创建Socket
  SocketTask = wx.connectSocket({
   url: url,
   data: 'data',
   header: {
    'content-type': 'application/json'
   },
   method: 'post',
   success: function (res) {
    console.log('WebSocket连接创建', res)
   },
   fail: function (err) {
    wx.showToast({
     title: '网络异常!',
    })
    console.log(err)
   },
  })
 },
 
 // 提交文字
 submitTo: function (e) {
  let that = this;
  var data = {
   body: that.data.inputValue,
  }
 
  if (socketOpen) {
   // 如果打开了socket就发送数据给服务器
   sendSocketMessage(data)
   this.data.allContentList.push({ is_my: { text: this.data.inputValue }});
   this.setData({
    allContentList: this.data.allContentList,
    inputValue: ''
   })
 
   that.bottom()
  }
 },
 bindKeyInput: function (e) {
  this.setData({
   inputValue: e.detail.value
  })
 },
 
 onHide: function () {
  SocketTask.close(function (close) {
   console.log('关闭 WebSocket 连接。', close)
  })
 },
 upimg: function () {
  var that = this;
   wx.chooseImage({
    sizeType: ['original', 'compressed'],
    success: function (res) {
     that.setData({
      img: res.tempFilePaths
     })
     wx.uploadFile({
      url: upload_url,
      filePath: res.tempFilePaths,
      name: 'img',
      success: function (res) {
       console.log(res)
        wx.showToast({
         title: '图片发送成功!',
         duration: 3000
        });
      }
     }) 
     that.data.allContentList.push({ is_my: { img: res.tempFilePaths } });
     that.setData({
      allContentList: that.data.allContentList,
     })
     that.bottom();
    }
   })
 },  
 addImg: function () {
  this.setData({
   addImg: !this.data.addImg
  })
 
 },
 // 获取hei的id节点然后屏幕焦点调转到这个节点 
 bottom: function () {
  var that = this;
  this.setData({
   scrollTop: 1000000
  })
 },
})
 
//通过 WebSocket 连接发送数据,需要先 wx.connectSocket,并在 wx.onSocketOpen 回调之后才能发送。
function sendSocketMessage(msg) {
 var that = this;
 console.log('通过 WebSocket 连接发送数据', JSON.stringify(msg))
 SocketTask.send({
  data: JSON.stringify(msg)
 }, function (res) {
  console.log('已发送', res)
 })
}

wxml

<view class='page_bg' wx:if='{{block}}' bindtap='hide_bg' />
<view class='btn_bg' wx:if='{{block}}'>
 <view wx:for="{{link_list}}" wx:key='index'>
  <button class="sp_tit" id='{{index}}' bindtap='list_item'>查看详情 {{item}} </button>
 </view>
</view>
<scroll-view class="history" scroll-y="true" scroll-with-animation scroll-top="{{scrollTop}}">
 
 <block wx:key="{{index}}" wx:for="{{allContentList}}">
  <!-- <view>
   <text class='time'>{{time}}</text>
  </view> -->
  <view class='my_right' wx:if="{{item.is_my}}">
   <view class='p_r' wx:if='{{item.is_my.text}}'>
    <text class='new_txt'><text class='new_txt_my'>{{item.is_my.text}}</text></text>
    <view class='sanjiao my'></view>
    <image class='new_img' src='/images/test.jpg'></image>
   </view>
   <view class='p_r' wx:if='{{item.is_my.img}}' bindtap='my_audio_click' data-id='{{index}}'>
    <text class='new_txt'> </text>
    <view class='my_img_bg'>
    <image class='my_audio' src='{{img}}'></image></view>
    <view class='sanjiao my'></view>
    <image class='new_img' src='/images/test.jpg'></image>
   </view>
  </view>
  <!-- <view class='you_left' id='id_{{allContentList.length}}'> -->
  <view class='you_left' id='id_{{allContentList.length}}' wx:key="{{index}}" wx:if="{{item.is_ai}}">
   <view class='p_r'>
    <image class='new_img' src='/images/chac.jpg'></image>
    <view class='sanjiao you'></view>
    <view class='new_txt'>
     <view class='new_txt_ai'>
      <!-- {{item.text}} -->
      <block wx:for='{{item.is_two}}' wx:key='index'>
       <text wx:if='{{item.text}}'>{{item.text}}</text>
       <text wx:if='{{item.a.title}}' style='color:#0000EE' bindtap='link' id='{{item.a.link}}'>{{item.a.title}}</text>
      </block>
     </view>
    </view>
   </view>
  </view>
 </block>
</scroll-view>
<view class="sendmessage">
 <image class='voice_icon' bindtap='addImg' src='/images/jia_img.png'></image>
 <block wx:if='{{!addImg}}'>
  <input type="text" bindinput="bindKeyInput" value='{{inputValue}}' focus='{{focus}}' bindfocus="focus" confirm-type="done" placeholder="" />
  <button bindtap="submitTo" class='user_input_text'>发送</button>
 </block>
 <block wx:if='{{addImg}}'>
  <view class='voice_ing' bindtap="upimg">发送图片</view>
 </block>
</view>

css

page { 
 background-color: #f2f2f2; 
 height: 100%;
} 
.jia_img{ 
 height: 80rpx; 
 width: 90rpx; 
} 
.time { 
 text-align: center; 
 padding: 5rpx 20rpx 5rpx 20rpx; 
 width: 200rpx; 
 font-size: 26rpx; 
 background-color: #E8E8E8; 
} 
.tab{
 bottom: 120rpx;
}
.tab_1{
 position: fixed;
 bottom: 50rpx;
 width: 200rpx;
 font-size: 26rpx;
 left: 50%;
 margin-left: -45rpx;
 height: 100rpx;
}
.tab_2{
 right: 30rpx;
 position: fixed;
}
/* 聊天 */ 
 
.my_right { 
 float: right; 
 margin-top: 30rpx;
 position: relative; 
 right: 40rpx; 
} 
.my_audio{
 height: 120rpx;
 width: 150rpx;
 position: absolute;
 right: 150rpx;
 background: white;
 top: 20rpx;
}
.my_img_bg{
 height: 150rpx;
 width: 400rpx;
 position: relative;
 right: 0;
 background: white;
 top: 20rpx;
}
.you_left { 
 margin-top: 30rpx;
 float: left; 
 position: relative; 
 left: 5rpx; 
} 
 
.new_img { 
 width: 100rpx; 
 height: 100rpx; 
 border-radius: 50%; 
} 
 
.new_txt { 
 width: 420rpx; 
} 
.new_txt_my{
 border-radius: 7px; 
 background-color: #fff; 
 margin-top: 10rpx;
 padding: 0rpx 30rpx 0rpx 30rpx; 
 float: right;
}
.new_txt_ai{
 border-radius: 7px; 
 background-color: #fff; 
 margin-top: 10rpx;
 padding: 0rpx 30rpx 0rpx 30rpx; 
 float: left;
}
.sanjiao { 
 top: 25rpx; 
 position: relative; 
 width: 0px; 
 height: 0px; 
 border-width: 15rpx; 
 border-style: solid; 
} 
 
.my { 
 border-color: transparent transparent transparent #fff; 
} 
 
.you { 
 border-color: transparent #fff transparent transparent; 
} 
 
.sendmessage { 
 width: 100%; 
 z-index: 2;
 display: flex; 
 position: fixed;
 bottom: 0px;
 background-color: #F4F4F6; 
 flex-direction: row; 
 height: 85rpx;
} 
.voice_icon{
 width: 60rpx;
 height: 60rpx;
 margin: 0 auto;
 padding: 10rpx 10rpx 10rpx 10rpx;
}
.voice_ing{
 width: 90%;
 height: 75rpx;
 line-height: 85rpx;
 text-align: center;
 border-radius: 15rpx;
 border: 1px solid #d0d0d0;
}
.sendmessage_2 { 
 z-index: 1;
 position: relative;
 width: 100%; 
 display: flex; 
 background-color: #F4F4F6; 
 flex-direction: row; 
 height: 85rpx;
}  
.sendmessage input { 
 width: 75%; 
 height: 60rpx;  
 background-color: white; 
 line-height: 60rpx; 
 font-size: 28rpx; 
 border-radius: 10rpx;
 margin-top: 10rpx;
 margin-left: 20rpx;
 border: 1px solid #d0d0d0; 
 padding-left: 20rpx; 
} 
.sendmessage button { 
 border: 1px solid white; 
 width: 18%; 
 height: 65rpx; 
 background: #00CC00;
 color: white;
 line-height: 65rpx; 
 margin-top: 10rpx;
 font-size: 28rpx; 
} 
 
.hei{ 
 height: 20rpx; 
} 
.history { 
 height: 80%; 
 padding: 20rpx 20rpx 20rpx 20rpx;
 font-size: 14px; 
 line-height: 50rpx; 
 word-break: break-all; 
} 
 
.icno_kf{
 position: fixed;
 bottom: 160rpx;
 margin: 0 auto;
 text-align: center;
 left: 50%;
 margin-left: -40rpx;
 width: 100rpx;
 height: 100rpx;
 border-radius: 50%
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript中的变量声明早于赋值分析
Mar 01 Javascript
js实现不提交表单获取单选按钮值的方法
Aug 21 Javascript
JS中this上下文对象使用方式
Oct 09 Javascript
js前端实现图片懒加载(lazyload)的两种方式
Apr 24 Javascript
关于vue.js组件数据流的问题
Jul 26 Javascript
mongoose更新对象的两种方法示例比较
Dec 19 Javascript
详解vue-meta如何让你更优雅的管理头部标签
Jan 18 Javascript
vue2.0 子组件改变props值,并向父组件传值的方法
Mar 01 Javascript
axios全局请求参数设置,请求及返回拦截器的方法
Mar 05 Javascript
Vue项目中跨域问题解决方案
Jun 05 Javascript
swiper实现异形轮播效果
Nov 28 Javascript
JS手写一个自定义Promise操作示例
Mar 16 Javascript
JavaScript实现的简单Tab点击切换功能示例
Jul 06 #Javascript
vue结合axios与后端进行ajax交互的方法
Jul 06 #Javascript
jQuery实现仿京东防抖动菜单效果示例
Jul 06 #jQuery
vue.js动画中的js钩子函数的实现
Jul 06 #Javascript
老生常谈JS中的继承及实现代码
Jul 06 #Javascript
vue.js使用v-if实现显示与隐藏功能示例
Jul 06 #Javascript
vue.js计算属性computed用法实例分析
Jul 06 #Javascript
You might like
PHP关于IE下的iframe跨域导致session丢失问题解决方法
2013/10/10 PHP
PHP中if和or运行效率对比
2014/12/12 PHP
Yii框架响应组件用法实例分析
2019/09/04 PHP
Highcharts 非常实用的Javascript统计图demo示例
2013/07/03 Javascript
鼠标左键单击冲突的问题解决方法(防止冒泡)
2014/05/14 Javascript
使用jQuery.form.js/springmvc框架实现文件上传功能
2016/05/12 Javascript
jQuery实现根据滚动条位置加载相应内容功能
2016/07/18 Javascript
原生js获取iframe中dom元素--父子页面相互获取对方dom元素的方法
2016/08/05 Javascript
a标签跳转到指定div,jquery添加和移除class属性的实现方法
2016/10/10 Javascript
js实现炫酷的左右轮播图
2017/01/18 Javascript
轻松理解JavaScript之AJAX
2017/03/15 Javascript
详解vue中computed 和 watch的异同
2017/06/30 Javascript
解决vue热替换失效的根本原因
2018/09/19 Javascript
ES6中字符串的使用方法扩展
2019/06/04 Javascript
浅析JavaScript预编译和暗示全局变量
2020/09/03 Javascript
[19:24]DOTA2客户端使用指南 一分钟快速设置轻松超神
2013/09/24 DOTA
[51:29]完美世界DOTA2联赛循环赛 Matador vs Forest BO2第一场 11.05
2020/11/05 DOTA
python读取浮点数和读取文本文件示例
2014/05/06 Python
python基础教程之基本数据类型和变量声明介绍
2014/08/29 Python
python中执行shell的两种方法总结
2017/01/10 Python
python MysqlDb模块安装及其使用详解
2018/02/23 Python
Python3安装Pillow与PIL的方法
2019/04/03 Python
python时间序列按频率生成日期的方法
2019/05/14 Python
jupyter notebook 参数传递给shell命令行实例
2020/04/10 Python
Django xadmin安装及使用详解
2020/10/26 Python
利用css3制作3D样式按钮实现代码
2013/03/18 HTML / CSS
美国知名运动产品零售商:Foot Locker
2016/07/23 全球购物
Tenstickers法国:墙贴和装饰贴纸
2019/08/26 全球购物
学院领导推荐信
2013/10/30 职场文书
开办饭店创业计划书
2013/12/28 职场文书
阿德的梦教学反思
2014/02/06 职场文书
园林技术专业求职信
2014/07/28 职场文书
2014年幼儿园重阳节活动方案
2014/09/16 职场文书
银行开户授权委托书格式
2014/10/10 职场文书
项目转让协议书
2014/10/27 职场文书
国情备忘录观后感
2015/06/04 职场文书