Android智能聊天机器人

        苹果有Siri,百度有小度,小米有小爱,而且后来竟然又出了个小兵,总之类似的智能聊天机器人是越来越多了。面对这样智能的机器人,我们似乎只能是体验者。想想底层的算法就让人头疼,它到底是怎么识别出一句话的意思的?又是怎么实现智能回复的?难道这就是传说中的机器学习、神经网络?不不不,其实这叫图灵机器人。也许底层算法真的很难很复杂,但如果你想实现一个自己的机器人,其实一点也不难。

        今天就手把手教大家实现一个属于自己的智能聊天机器人。

 

        首先我们百度图灵机器人,进入官网,网址为http://www.tuling123.com/

        点击右上角的小头像便可以进入控制台了

 来到控制台我们就可以根据自己的需求创建机器人了,过程没什么难度,这里有一点需要注意,当我们创建完成之后点击设置

会进入到如下界面

注意这个密钥开关,不要打开,不要打开,不要打开!!!否则在开发过程中会报40001:加密方式错误。

        如果大家自学能力比较强可以直接看文档接入,不懂的地方再来借鉴一下。文档地址为

https://www.kancloud.cn/turing/www-tuling123-com/718227这里也有一点需要注意,接口地址只允许post请求访问,我们直接用浏览器是无法访问的。所以不要以为浏览器不能访问接口就不能用了。

        必要的准备工作已经完成了,下面进入开发阶段。

        整个聊天机器人的核心思想就是将用户发送的信息通过post请求访问图灵机器人接口,然后解析接口返回的数据,将有用的回复信息提取出来显示到界面上。

        首先创建一个工具类叫做HttpUtils用来处理网络请求。用原生的HttpUrlConnection也可以完成,但远远不如OkHttp用起来方便,因此我们选择OkHttp来进行网络请求,打开app的build.gradle文件,在dependencies中加入

implementation 'com.squareup.okhttp3:okhttp:3.12.1'//用于处理网络请求
implementation 'com.google.code.gson:gson:2.8.5'//用于解析json数据
implementation 'de.hdodenhof:circleimageview:3.0.0'//用于处理圆形头像

不要忘了声明权限

    <uses-permission android:name="android.permission.INTERNET"/>

然后实现我们的网络请求方法

    /*** 使用OkHttp自身回调请求数据* @param msg* @param callback* enqueue()方法中会自动开启线程*/public static void sendOkHttpRequest(String msg, okhttp3.Callback callback) {OkHttpClient client = new OkHttpClient();final String json = "{" +"\"reqType\":0," +"    \"perception\": {" +"        \"inputText\": {" +"            \"text\": \"" + msg + "\"" +"        }," +"        \"inputImage\": {" +"            \"url\": \"\"" +"        }," +"        \"selfInfo\": {" +"            \"location\": {" +"                \"city\": \"天津\"," +"                \"province\": \"天津\",\n" +"                \"street\": \"天津理工大学\"\n" +"            }" +"        }" +"    }," +"    \"userInfo\": {" +"        \"apiKey\": \"" + API_KEY + "\"," +"        \"userId\": \"" + "572780350" + "\"" +"    }" +"}";RequestBody body = RequestBody.create(JSON,json);Request request = new Request.Builder().url(URL).post(body).build();//注意这里用的是enqueue()方法,此方法会在内部自动开启一个线程client.newCall(request).enqueue(callback);}

        至于我们为什么这样构建请求体呢,那是因为官方文档中给出了请求示例。 我们只需要将inputText下面的text内容替换为用户输入的信息,并将userInfo下面的apikey替换为我们创建机器人时得到的apikey就可以了。此外还需要将userId替换为一个长度小于等于32位的字符串,用于标识用户,这里我用了自己的QQ号。

        可以看到里面有很多请求信息,其中某些是必须要填写 的,还有一些是不必须的,具体大家可以查看文档。

 

        还有一点需要注意的是网络请求需要在子线程中进行,而我们并没有开启子线程,而是在方法中接收了一个 okhttp3.Callback类型的参数。而且也没有像往常一样使用client.newCall(request).execute();方法,而是调用了

client.newCall(request).enqueue(callback);方法。其实enqueue()方法内部已经自动帮我们开启了子线程,我们只需要在调用的时候实现okhttp3提供的callback接口就可以轻松处理返回的数据了。

        当然,如果你不习惯使用okhttp3提供的callback接口的话,可以实现自己的接口,并在自己定义的接口中处理返回数据,就像下面这样。

    /*** 自己构造回调方法请求数据,测试时使用* @param msg* @param listener* 因为是网络请求,因此需要开启线程*/public static void doRequest(String msg, final HttpCallbackListener listener) {final String json = "{" +"\"reqType\":0," +"    \"perception\": {" +"        \"inputText\": {" +"            \"text\": \"" + msg + "\"" +"        }," +"        \"inputImage\": {" +"            \"url\": \"\"" +"        }," +"        \"selfInfo\": {" +"            \"location\": {" +"                \"city\": \"天津\"," +"                \"province\": \"天津\",\n" +"                \"street\": \"天津理工大学\"\n" +"            }" +"        }" +"    }," +"    \"userInfo\": {" +"        \"apiKey\": \"" + API_KEY + "\"," +"        \"userId\": \"" + "572780350" + "\"" +"    }" +"}";new Thread(new Runnable() {@Overridepublic void run() {String strResult = "";Response responseData = null;OkHttpClient client = new OkHttpClient();RequestBody body = RequestBody.create(JSON,json);Request request = new Request.Builder().url(URL).post(body).build();try {responseData = client.newCall(request).execute();String response = responseData.body().string();Log.d("xxx","请求成功" + responseData);strResult = parJson(response);if(listener != null) {listener.finish(strResult);}} catch (IOException e) {e.printStackTrace();if(listener != null) {listener.onError(e);}} finally {responseData.body().close();}}}).start();}

其中的HttpCallbackListener接口定义如下,分别处理请求成功的信息,和请求失败的情况。

public interface HttpCallbackListener {void finish(String response);void onError(Exception e);
}

然后就可以在主活动中对接口进行测试了,当点击按钮使调用我们封装的

public static void sendOkHttpRequest(String msg, okhttp3.Callback callback)方法,其中第一个参数填写自定义的消息内容,第二个参数是一个callback接口像下面一样就可以了。

注意:onFailure()和onResponse()方法中依然处于子线程中,不能在这两个方法中更新UI界面,即不能将返回的json信息直接显示在界面上,我们可以通过Log日志的形式将其打印出来。

        /*** 当点击发送按钮时* 首先获取用户输入的信息,调用adapter.notifyDataSetChanged();方法将其显示到listview中* 再调用我们封装的sendOkHttpRequest()方法从接口请求返回的数据* 注意此时实现需要okhttp3.Callback接口中的onFailure()和onResponse()方法,分别表示请求失败和请求成功的情况* onFailure()和onResponse()方法中依然处于子线程中,如果需要更新界面需要调用runOnUiThread()方法* 或使用handler,我们这里选择使用handler*/btnSendRequest.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String message = etMsgContent.getText().toString().trim();if(TextUtils.isEmpty(message)) {return;}ChatMessage toMessage = new ChatMessage(message,new Date(), ChatMessage.Type.OUTCOMING);data.add(toMessage);
//                nowTime = System.currentTimeMillis();
//                if(nowTime - lastTime > 5 * 1000) {
//                    tvToTime.setVisibility(View.VISIBLE);
//                } else {
//                    tvToTime.setVisibility(View.GONE);
//                }
//                lastTime = nowTime;adapter.notifyDataSetChanged();lvChatMessage.setSelection(adapter.getCount()-1);etMsgContent.setText("");HttpUtils.sendOkHttpRequest(message,new okhttp3.Callback(){@Overridepublic void onFailure(Call call, IOException e) {//请求过程中出现错误的回调e.printStackTrace();Toast.makeText(MainActivity.this,"请求过程中出错了",Toast.LENGTH_SHORT).show();}@Overridepublic void onResponse(Call call, final Response response) throws IOException {//请求成功的回调final String strResponse = parJson(response.body().string());//从返回的Json数据中解析出有用的数据ChatMessage fromMessage = new ChatMessage(strResponse,new Date(),ChatMessage.Type.INCOMING);Message message2 = new Message();message2.obj = fromMessage;handler.sendMessage(message2);}});}});

发送“你好”,打印出来的日志大概是这样的。这和官方文档中展示的返回数据示例不太一样,因此我们需要根据具体的数据格式来解析json数据。

        其实到这里我们的智能聊天机器人已经完成了,可以发送信息,可以返回数据。只是看起来有点low,发送的信息只能在程序中写死,返回的数据也是一大堆json数据,半天找不到重点。

        至于如何做出精美的聊天界面就不是我们今天讨论的范围了。整个项目已经上传到github,点击这里进行下载。其实整个项目的实现在文章中三言两语是解释不清楚的,尤其是一些细节,很难顾及到,建议大家多研究github上面优秀的开源项目,在真正的项目中逐渐成长。

        下面将整个项目的主要代码展示在下面

HttpUtils
package com.example.utils;import android.util.Log;import com.example.bean.Result;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;import java.io.IOException;import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;public class HttpUtils {private static final String URL = "http://openapi.tuling123.com/openapi/api/v2";private static final String API_KEY = "7bdfd1b20f084b8089eeaf289799c68d";public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");/*** 使用OkHttp自身回调请求数据* @param msg* @param callback* enqueue()方法中会自动开启线程*/public static void sendOkHttpRequest(String msg, okhttp3.Callback callback) {OkHttpClient client = new OkHttpClient();final String json = "{" +"\"reqType\":0," +"    \"perception\": {" +"        \"inputText\": {" +"            \"text\": \"" + msg + "\"" +"        }," +"        \"inputImage\": {" +"            \"url\": \"\"" +"        }," +"        \"selfInfo\": {" +"            \"location\": {" +"                \"city\": \"天津\"," +"                \"province\": \"天津\",\n" +"                \"street\": \"天津理工大学\"\n" +"            }" +"        }" +"    }," +"    \"userInfo\": {" +"        \"apiKey\": \"" + API_KEY + "\"," +"        \"userId\": \"" + "572780350" + "\"" +"    }" +"}";RequestBody body = RequestBody.create(JSON,json);Request request = new Request.Builder().url(URL).post(body).build();//注意这里用的是enqueue()方法,此方法会在内部自动开启一个线程client.newCall(request).enqueue(callback);}/*** 自己构造回调方法请求数据,测试时使用* @param msg* @param listener* 因为是网络请求,因此需要开启线程*/public static void doRequest(String msg, final HttpCallbackListener listener) {final String json = "{" +"\"reqType\":0," +"    \"perception\": {" +"        \"inputText\": {" +"            \"text\": \"" + msg + "\"" +"        }," +"        \"inputImage\": {" +"            \"url\": \"\"" +"        }," +"        \"selfInfo\": {" +"            \"location\": {" +"                \"city\": \"天津\"," +"                \"province\": \"天津\",\n" +"                \"street\": \"天津理工大学\"\n" +"            }" +"        }" +"    }," +"    \"userInfo\": {" +"        \"apiKey\": \"" + API_KEY + "\"," +"        \"userId\": \"" + "572780350" + "\"" +"    }" +"}";new Thread(new Runnable() {@Overridepublic void run() {String strResult = "";Response responseData = null;OkHttpClient client = new OkHttpClient();RequestBody body = RequestBody.create(JSON,json);Request request = new Request.Builder().url(URL).post(body).build();try {responseData = client.newCall(request).execute();String response = responseData.body().string();Log.d("xxx","请求成功" + responseData);strResult = parJson(response);if(listener != null) {listener.finish(strResult);}} catch (IOException e) {e.printStackTrace();if(listener != null) {listener.onError(e);}} finally {responseData.body().close();}}}).start();}private static String parJson(String responseData) {Gson gson = new Gson();String strResult = "";Result result = gson.fromJson(responseData,new TypeToken<Result>(){}.getType());strResult = result.getResults().get(0).getValues().getText();Log.d("xxx","返回的结果为:" + strResult);return strResult;}//    {
//        "emotion":
//        {
//            "robotEmotion":
//            {
//                "a":0,"d":0,"emotionId":0,"p":0
//            },
//            "userEmotion":
//            {
//                "a":0,"d":0,"emotionId":10300,"p":0
//            }
//        },
//        "intent":
//        {
//            "actionName":"",
//                "code":10004,
//                "intentName":""
//        },
//        "results":
//        [
//                {
//                    "groupType":1,
//                        "resultType":"text",
//                        "values":
//                    {
//                        "text":"你陪我玩我就好啦"
//                    }
//                }
//        ]
//    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#F0F2F8"tools:context="com.example.activity.MainActivity"><android.support.v7.widget.Toolbarandroid:id="@+id/tool_bar"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"android:background="@drawable/top_bar_bg"app:title="小新"android:layout_alignParentTop="true"android:theme="@style/Base.ThemeOverlay.AppCompat.Dark.ActionBar"app:popupTheme="@style/Theme.AppCompat.Light"/><ListViewandroid:id="@+id/list_chat_msg"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_below="@id/tool_bar"android:layout_above="@+id/bottom_bar"android:divider="@null"android:dividerHeight="4dp"/><LinearLayoutandroid:id="@+id/bottom_bar"android:layout_width="match_parent"android:layout_height="40dp"android:layout_alignParentBottom="true"android:gravity="center_vertical"android:orientation="horizontal"android:padding="4dp"><EditTextandroid:id="@+id/et_message_content"android:layout_width="0dp"android:layout_weight="1"android:layout_height="36dp"android:layout_marginRight="4dp"android:background="@drawable/edit_msg_bg"/><Buttonandroid:id="@+id/btn_send_request"android:layout_width="56dp"android:layout_height="40dp"android:minHeight="0dp"android:maxLines="1"android:background="@drawable/btn_sended"android:textColor="#FFFFFF"android:text="发送"/></LinearLayout></RelativeLayout>

MainActivity

package com.example.activity;import android.media.MediaExtractor;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;import com.example.adapter.ChatMessageAdapter;
import com.example.bean.ChatMessage;
import com.example.bean.Result;
import com.example.myrobot.R;
import com.example.utils.HttpCallbackListener;
import com.example.utils.HttpUtils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;import okhttp3.Call;
import okhttp3.Response;public class MainActivity extends AppCompatActivity {private Button btnSendRequest;private EditText etMsgContent;private ListView lvChatMessage;private ChatMessageAdapter adapter;private List<ChatMessage> data;private TextView tvToTime;private TextView tvFromTime;private long lastTime;private long nowTime;private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);ChatMessage message = (ChatMessage) msg.obj;data.add(message);adapter.notifyDataSetChanged();lvChatMessage.setSelection(adapter.getCount()-1);}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initToolBar();initData();initView();initEvent();}private void initData() {data = new ArrayList<>();data.add(new ChatMessage("很高兴为您服务,主人",new Date(), ChatMessage.Type.INCOMING));lastTime = System.currentTimeMillis();}private void initEvent() {/*** 当点击发送按钮时* 首先获取用户输入的信息,调用adapter.notifyDataSetChanged();方法将其显示到listview中* 再调用我们封装的sendOkHttpRequest()方法从接口请求返回的数据* 注意此时实现需要okhttp3.Callback接口中的onFailure()和onResponse()方法,分别表示请求失败和请求成功的情况* onFailure()和onResponse()方法中依然处于子线程中,如果需要更新界面需要调用runOnUiThread()方法* 或使用handler,我们这里选择使用handler*/btnSendRequest.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String message = etMsgContent.getText().toString().trim();if(TextUtils.isEmpty(message)) {return;}ChatMessage toMessage = new ChatMessage(message,new Date(), ChatMessage.Type.OUTCOMING);data.add(toMessage);
//                nowTime = System.currentTimeMillis();
//                if(nowTime - lastTime > 5 * 1000) {
//                    tvToTime.setVisibility(View.VISIBLE);
//                } else {
//                    tvToTime.setVisibility(View.GONE);
//                }
//                lastTime = nowTime;adapter.notifyDataSetChanged();lvChatMessage.setSelection(adapter.getCount()-1);etMsgContent.setText("");HttpUtils.sendOkHttpRequest(message,new okhttp3.Callback(){@Overridepublic void onFailure(Call call, IOException e) {//请求过程中出现错误的回调e.printStackTrace();Toast.makeText(MainActivity.this,"请求过程中出错了",Toast.LENGTH_SHORT).show();}@Overridepublic void onResponse(Call call, final Response response) throws IOException {//请求成功的回调final String strResponse = parJson(response.body().string());//从返回的Json数据中解析出有用的数据ChatMessage fromMessage = new ChatMessage(strResponse,new Date(),ChatMessage.Type.INCOMING);Message message2 = new Message();message2.obj = fromMessage;handler.sendMessage(message2);}});}});etMsgContent.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {String content = etMsgContent.getText().toString().trim();if(TextUtils.isEmpty(content)) {btnSendRequest.setBackgroundResource(R.drawable.btn_sended);} else {btnSendRequest.setBackgroundResource(R.drawable.btn_sending);}}@Overridepublic void afterTextChanged(Editable s) {}});}private void initView() {btnSendRequest = findViewById(R.id.btn_send_request);etMsgContent = findViewById(R.id.et_message_content);tvToTime = findViewById(R.id.tv_to_time);tvFromTime = findViewById(R.id.tv_from_time);lvChatMessage = findViewById(R.id.list_chat_msg);adapter = new ChatMessageAdapter(this,data);lvChatMessage.setAdapter(adapter);}private void initToolBar() {Toolbar toolbar = findViewById(R.id.tool_bar);setSupportActionBar(toolbar);ActionBar actionBar = getSupportActionBar();if(actionBar != null) {actionBar.setDisplayHomeAsUpEnabled(false);}}private String parJson(String responseData) {Gson gson = new Gson();String strResult = "";Result result = gson.fromJson(responseData,new TypeToken<Result>(){}.getType());strResult = result.getResults().get(0).getValues().getText();Log.d("xxx","返回的结果为:" + strResult);return strResult;}
}
ChatMessageAdapter
package com.example.adapter;import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;import com.example.bean.ChatMessage;
import com.example.myrobot.R;import java.text.SimpleDateFormat;
import java.util.List;public class ChatMessageAdapter extends BaseAdapter {private LayoutInflater mInflater;private List<ChatMessage> mData;public ChatMessageAdapter(Context context,List<ChatMessage> data) {this.mInflater = LayoutInflater.from(context);this.mData = data;}@Overridepublic int getCount() {return mData.size();}@Overridepublic Object getItem(int position) {return mData.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic int getItemViewType(int position) {ChatMessage chatMessage = mData.get(position);if(chatMessage.getType() == ChatMessage.Type.INCOMING) {return 0;}return 1;}@Overridepublic int getViewTypeCount() {return 2;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = null;if(convertView == null) {holder = new ViewHolder();if(getItemViewType(position) == 0) {convertView = mInflater.inflate(R.layout.item_from_layout,parent,false);holder.tvMessageDate = convertView.findViewById(R.id.tv_from_time);holder.tvMessageContent = convertView.findViewById(R.id.tv_from_msg_info);} else {convertView = mInflater.inflate(R.layout.item_to_layout,parent,false);holder.tvMessageDate = convertView.findViewById(R.id.tv_to_time);holder.tvMessageContent = convertView.findViewById(R.id.tv_to_msg_info);}convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}ChatMessage message = mData.get(position);SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");holder.tvMessageDate.setText(format.format(message.getDate()));holder.tvMessageContent.setText(message.getContent());return convertView;}private class ViewHolder {TextView tvMessageDate;TextView tvMessageContent;}
}
ChatMessage
package com.example.bean;import java.util.Date;public class ChatMessage {private String content;private Date date;private Type type;public enum Type{INCOMING,OUTCOMING}public ChatMessage(String content, Date date, Type type) {this.content = content;this.date = date;this.type = type;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public Date getDate() {return date;}public void setDate(Date date) {this.date = date;}public Type getType() {return type;}public void setType(Type type) {this.type = type;}
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/49069.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

德国IT行业薪酬水平大揭秘--2020

点击 欧盟IT那些事 关注我们 公告&#xff1a;因企鹅审核规定&#xff0c;本公众号从《德国IT那些事》更名为《欧盟IT那些事》。 所有脱离工龄、级别、职位、经验、城市以及裙带关系来谈论工资&#xff0c;都是耍流氓&#xff01; 一般来说IT行业公司&#xff0c;资历是按等级划…

德国IT行业薪酬水平大揭秘--2023

点击 欧盟IT那些事 关注我们 公告&#xff1a;因企鹅审核规定&#xff0c;本公众号从《德国IT那些事》更名为《欧盟IT那些事》。 所有脱离工龄、级别、职位、经验、城市以及裙带关系来谈论工资&#xff0c;都是耍流氓&#xff01;2022-23年&#xff0c;SAP行业薪酬异军突起&…

当事务Transactional遇见异步线程出现的坑

问题 开发小伙伴遇到线上环境消息推送不成功&#xff0c;排查日志发现推送是id为null 代码示例 Transactional(rollbackFor Exception.class) public void register(UserDTO dto) {User user BeanCopyUtils.copyBean(dto, User.class);insert(user);//注册成功消息推送exe…

511遇见电脑PC任意多开绿色软件

电脑端的微信只能单开&#xff0c;为了工作方便需要&#xff0c;我们有时候需要开启多个微信账号&#xff0c;511遇见制作一个微信多开端。 微信vx多开器特点 1.支持自动获取电脑上的微信安装路径 2.支持手动获取微信安装路径 3.支持所有版本的微信多开 4.支持自定义任意多开数…

当互联网码农遇见国企老同学

本文转载自程序员技术 码农张小北和国企职员王志强&#xff0c; 是同一所大学、同一个专业、同一间宿舍&#xff0c; 睡上下铺的兄弟。 毕业那年&#xff0c; 性格沉闷的张小北去了互联网公司&#xff0c; 善于处事的王志强选择了一家国企。 两个不同的选择&#xff0c; 在…

抖音直播带货数据统计,直播带货要复盘哪些数据指标

抖音直播电商数据分析需要围绕“带货”这个核心目标展开,这其中就涉及到“人、货、场”这三个概念,也就是抖音直播的流量、商品和直播间。 这三个概念组合起来,就是抖音直播电商需要关注的核心问题,也是我们数据分析的重点: 1. 不同商品适合在什么类型的直播间推广? 商品在…

带货直播系统,实现直播重要的一步——推流

什么是rtmp&#xff1f; RTMP是Real Time Messaging Protocol&#xff08;实时消息传输协议&#xff09;的首字母缩写。该协议基于TCP&#xff0c;是一个协议族&#xff0c;包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种。RTMP是一种设计用来进行实时数据通信的网络协议&…

虚拟主播也带货?直播电商的变与不变

5月6日晚&#xff0c;海外虚拟主播vox在B站开启了中国直播首秀。从最终数据来看&#xff0c;直播1.7小时&#xff0c;营收111万人民币&#xff0c;当晚还登上平台热门首位&#xff0c;这样的直播吸金能力&#xff0c;让不少明星都望尘莫及。 更值得关注的是&#xff0c;直播间…

直播带货行业如何入局?先了解一下直播商城源码吧

直播行业的爆火已经持续了多个年头&#xff0c;直到今天&#xff0c;在人们的生活中依然有着举足轻重的地位&#xff0c;它通过多元化的方案为许多行业带来了新的思路&#xff0c;特别是与传统商业所结合的“直播电商”、“直播商城”的卖货新形式&#xff0c;让多方因此而受益…

抖音直播带货数据统计,抖音直播带货复盘必看的4个数据

在每一次抖音直播结束后&#xff0c;都会将这一场数据呈现给我们&#xff0c;而我们要对数据进行分析总结。很多人在分析数据的时候&#xff0c;不知道要分析哪些数据&#xff0c;其实我们在复盘的时候&#xff0c;一定要注意这4个数据&#xff0c;这四个数据可以很全面的反应直…

直播前、直播中、直播后...直播带货技巧大盘点

直播带货已经成为2020年商家营销的一个必要渠道&#xff0c;随着移动互联网发展日益壮大&#xff0c;全国各大行业基本上已经普及了网络化&#xff0c;直播行业已经成为炙手可热的话题。 “万物皆可直播”这是前段时间网上盛传的一句话&#xff0c;是啊&#xff0c;万物皆可直…

直播带货系统,实现直播间人数统计

实现直播带货系统直播间的上下滚动人数计数器&#xff1a; css&#xff1a; .sdvm_num{! font-size: 14px;color:red;display:inline-block;vertical-align:middle;margin-left:8px;} .sdvm_num i{width:70px;height:52px;display:inline-block;background:url(../images/num…

直播带货app源码,实现直播连麦和PK

一、概述 连麦&#xff1a;是指直播带货app源码中&#xff0c;由观众向主播发起连线请求&#xff0c;在主播和该观众之间建立低延迟的通讯链路&#xff0c;而其他观众可以看到“主播连麦观众”的合成音视频内容。PK&#xff1a;是指直播过程中&#xff0c;由主播发起&#xff…

DBS的组成、DBS的全局结构、DBS结构的分类

概述&#xff1a;这在知识体系中都是目录式的知识&#xff0c;把它整理出来&#xff0c;形成图即可。

DB,DBMS,DBS之间的关系

数据库(Database,简称DB)是指&#xff1a;长期储存在计算机内的、有组织的、可共享的大量数据集合。一个应用系统通常包含多个数据库。 数据库管理系统&#xff08;Database Management System&#xff0c;简称DBMS&#xff09;是位于用户&#xff08;应用程序&#xff09;与操…

DBS小结

《数据库系统原理》主要介绍的是数据库技术的基本原理、方法和应用技术。 它可以使我们能有效地使用现有的数据库管理系统和软件开发工具&#xff0c;掌握数据库结构的设计和数据库应用系统的开发原理。 在这里&#xff0c;将这本书分为概念部分、方法部分和应用技术部分。

实战案例丨GaussDB for DWS如何识别坏味道的SQL

摘要&#xff1a;SQL中的坏味道&#xff0c;你知道吗&#xff1f; SQL语言是关系型数据库&#xff08;RDB&#xff09;的标准语言&#xff0c;其作用是将使用者的意图翻译成数据库能够理解的语言来执行。人类之间进行交流时&#xff0c;同样的意思用不同的措辞会产生不同的效果…

GBase 8s 数据库监控(4)

5&#xff0e;Session 的连接情况 通过 Session 的连接信息&#xff0c;可以分析出数据库系统业务的负载情况以及来自哪些客户端的任务较多&#xff0c;并且根据 Session 的空闲情况判断客户端连接池是否存在过多的连接。查询 Session 连接情况的 SQL 语句如下。 SELECT s.sid…

一篇就够了-带你走进DB2分区

目录 先决条件&#xff1a; DB2数据库分区 1、概念描述 2、DPF对数据库性能产生的影响 3、DB2分区与Oracle的比较 4、总结 进入正文&#xff1a; 简介 特性概述 三个互补的 CREATE TABLE 选项 简要对比 互补特性 表设计 表设计的经验法则 设计的例子 再添上 MQ…

GBase8s 数据库实例化

1.切换到数据库用户gbasedbt su - gbasedbt 2.切换到目录/opt/gbase/etc, 执行实例化脚本GBaseInit_gbasedbt.sh: cd /opt/gbase/etc sh GBaseInit_gbasedbt.sh 3.实例名称使用默认值gbaseserver: ENTER THE INSTANCE INFORMATION or PRESS <ENTER> TO ACCEPT THE D…